Ir al contenido principal

Cómo probamos las pruebas. Utilidad Suppressor

Las prácticas del curso de pruebas difieren significativamente de las prácticas de otros cursos. Por lo general, se le pide que escriba la implementación de una función para un conjunto existente de pruebas. Aquí es al revés. Debe escribir pruebas para un código existente, y el sistema debe verificar la corrección de las pruebas escritas.

Veamos cómo funciona esta práctica con un ejemplo concreto. Imagina una función llamada last(), que devuelve el último elemento de un array:

code1.png

¿Se puede afirmar con certeza que funciona correctamente basándonos en el ejemplo anterior? No. Es totalmente posible que esta función esté implementada de la siguiente manera:

code2.png

En este caso, se necesitaría otra llamada para verificar su funcionamiento:

code3.png

¿Es suficiente ahora? Nuevamente no. Su código podría ser así:

code4.png

Con tal implementación, tanto la primera como la segunda llamada devolverían los datos correctos, aunque la función está implementada incorrectamente. Aquí está la implementación correcta de la función:

code5.png

Sin profundizar en los detalles de cómo funcionan las pruebas, se puede ver para qué sirven. Con ellas, podemos asegurarnos de que el código, en este caso la función, funcione correctamente para diferentes datos de entrada, no solo en un caso específico.

Existe exactamente una buena manera de verificar si has escrito las pruebas correctamente: ejecutar estas pruebas con diferentes implementaciones de la función. Si la implementación es correcta, las pruebas deberían pasar con éxito; de lo contrario, deberían fallar con un error. Este enfoque permite evaluar la efectividad de las pruebas, no cómo están escritas.

¿Cómo funciona técnicamente la verificación de las pruebas?

En el código de la lección se crea un módulo JS que contiene varias implementaciones diferentes del código que se debe probar. Así es como se verá este archivo en el caso de probar la función last():

code6.png

En el archivo de pruebas, este módulo se importa de la siguiente manera:

code7.png

Ahora, la parte más interesante. En cada ejercicio, hay un archivo «Makefile», y al abrirlo se puede ver cómo se ejecutan las pruebas:

code8.png

En este archivo, se ejecutan las pruebas para cada una de las implementaciones de la función a probar del archivo functions.js.

Nuestro sistema de verificación utiliza una biblioteca especial llamada «Suppressor» para ejecutar las pruebas. Esta biblioteca puede determinar si las pruebas se completaron con éxito. Tiene dos modos de funcionamiento:

Suppressor verifica que las pruebas se hayan completado con éxito. En esta verificación, la implementación correcta de la función que se está probando se sustituye en sus pruebas (sin errores).

code9.png
El argumento pass indica que Suppressor espera que las pruebas se completen con éxito. El siguiente argumento es el comando que se debe ejecutar. En caso de éxito, se imprimirá el mensaje:
 

code10.png

Esto significa que para la implementación actual se utilizó una versión de trabajo (correcta) del código, para la cual las pruebas deberían haberse completado con éxito. Si las pruebas fallaron, significa que están escritas incorrectamente.

En el archivo Makefile, la línea de ejecución puede no incluir la variable de entorno FUNCTION_VERSION:

code11.png

En este caso, Suppressor utilizará la implementación correcta de la función, que es right1.

Suppressor verifica que las pruebas fallen. En esta ejecución, las pruebas se realizan con una implementación incorrecta de la función que se está probando. Las pruebas bien escritas deberían encontrar el error y señalarlo, es decir, deberían fallar.

code12.png   
El argumento fail indica que Suppressor espera que el comando ejecutado falle. Esto significa que las pruebas están escritas correctamente y la biblioteca imprimirá el mensaje:

code13.png  


Si el comando se ejecuta correctamente, la biblioteca imprimirá el siguiente mensaje:

code14.png
Esto significa que para la implementación actual se utilizó una versión incorrecta (no funcional) del código, para la cual las pruebas deberían haber fallado (indicado un error). Si las pruebas no fallaron, significa que están escritas incorrectamente.