Cuando se están escribiendo test, estos tienen una estructura en común (Bill Wake la denominó estructura 3A):
• Arrange: crear algunos objetos.
• Act: estimular estos objetos.
• Assert: verificar el resultado.
En este punto se plantean dos posibles problemas:
• El rendimiento: los test deberían ejecutarse tan rápido como sea posible y la creación de objetos requiere un cierto tiempo. Es posible crear objetos que sean comunes a los distintos test.
• El aislamiento: los test deberían ser independientes unos de otros.
El acoplamiento de test se produce cuando el resultado de un test depende de otro test. Esto hay que evitarlo ya que los test deberían ser independientes estar aislados.
Asumiendo que el rendimiento no es actualmente un problema, la estrategia debería centrarse en el aislamiento de los test.
Revisamos la lista de tareas para saber con qué tarea continuar:
•
• Ejecutar «setUp» primero.
• Ejecutar «tearDown» después.
• Ejecutar «tearDown» incluso si el método falla.
• Ejecutar multiples test.
• Informar de los resultados.
En este capítulo se aborda la ejecución de un método «setUp» antes de la ejecución del método de prueba. El enfoque para desarrollar esta funcionalidad va a ser similar al de la ejecución del método de prueba ya que para saber si el método «setUp» se ha ejecutado vamos a utilizar un nuevo indicador o «flag»: «wasSetUp».
Para realizar la implementación vamos a partir de un ejemplo específico y en lugar de sacar valores por la consola se va a incluir una aserción («assert») para verificar que está funcionando correctamente.
En este punto Kent Beck entiende esto como una prueba que debería estar dentro de un método de prueba. Así que se crea la clase «TestCaseTest», que extiende de «TestCase» e implementa el método «testSetUp». Este método de prueba contiene la creación de una instancia «WasRun», su ejecución y la verificación de que «wasSetUp» tiene el valor correcto a través de una aserción de tipo «assert». Es una prueba que contiene a su vez otra prueba (como diría Tony Stark: «¿y por qué no?»).
Añadimos la prueba a «main» para su ejecución:
Si lo ejecutamos obtenemos un error ya que no está definido el atributo «wasSetUp». Así que vamos a definir el atributo «wasSetUp» y un método para asignar el valor en la clase «WasRun».
Si ejecutamos el script «main» obtenemos una excepción lanzada por el método «assert» del método de prueba. Así que sólo tendríamos que hacer la llamada al método «setUp» para asignar el valor esperado por «assert», o sea, «true».
¿Cuándo debería hacerse la llamada al método «setUp()»? Esta llamada debería hacerse siempre justo antes de ejecutar un método de prueba. Los métodos de prueba se ejecutan en el método «run()» de la clase padre «TestCase» por lo que este es el lugar para hacer la llamada. También hay que definir la función «setUp()» en «TestCase» para que funcione correctamente:
Si se ejecuta «main» no se produce ningún error.
En este momento podemos refactorizar así que se puede mover la inicialización del atributo «wasRun» al método «setUp» de manera que se puede prescindir del constructor de la clase y este se simplifica.
Si se ejecuta funciona correctamente.
También se puede crear un método de prueba para comprobar si un método se ha ejecutado. Se va a crear un test dentro de «TestCaseTest» para comprobar «wasRun».
Se crea el objeto y la llamada en el archivo «main».
Si ejecutamos «main» funciona correctamente.
Se pueden simplificar los métodos de prueba ya que ambos crean una instancia de «WasRun».Esta instancia se puede crear durante el método de «setUp()» y usarla en los métodos de prueba. Como cada prueba crea una instancia al inicio de su ejecución los métodos de prueba no estarían acoplados entre sí (salvo que haya alguna variable global o similar).
Así que creamos un atributo «test» en «TestCaseTest» y sobrecargamos el método «setUp()» para crear una nueva instancia de «WasRun».
En este capítulo se ha visto:
• La simplicidad de escribir las pruebas prima sobre el rendimiento de las mismas de ahí que cada test corra su propia instancia de «wasRun».
• Se ha testeado e implementado «setUp()».
• Se ha simplificado el caso de prueba usando «setUp()».
• Se ha simplificado los caso de prueba verificando el ejemplo de test case.
Ya podemos tachar de la lista la segunda tarea:
•
•
• Ejecutar «tearDown» después.
• Ejecutar «tearDown» incluso si el método falla.
• Ejecutar multiples test.
• Informar de los resultados.
No hay comentarios:
Publicar un comentario