El happy path en los tests (o los tests felices)
Un artículo de Rafa G. Blanes
Reconozco que comencé a tomarme muy en serio el ser más estricto con el desarrollo y refactorings de las pruebas desde hace relativamente pocos años. Efectivamente, me llevó su tiempo darme cuenta de la enorme rentabilidad metodológica al pasar de una aplicación de consola para depurar (...) que tener formalizadas correctamente una completa y contundente batería de pruebas. Tanto es así, que hoy día sólo veo a través de las pruebas, quiero decir, cuando desarrollo nuevo código de producción, pocas veces entro en él en modo depuración si las pruebas correspondientes indican que todo va bien.
(Update: no en vano he publicado en 2019 un nuevo trabajo sobre todas aquellas prácticas ágiles que permiten escribir código mejor diseñado y de mejor calidad y que permite así escribir mejores tests: El Libro Práctico del Programador Ágil)
No obstante, y sin caer en la simpleza de reconocer lo fácil que es detectar en qué otros fallan, veo a menudo (muchas más veces de las que me gustaría) que el hecho de tener implantantado una arquitectura y metodología que permite y exige el crear pruebas, éstas se desarrollan como para salir del paso, en lo que se suele en llamar el happy path y que yo llamo particularmente "pruebas felices".
¿Qué es una prueba feliz?. Cuando escribimos una nueva clase o añadimos una nueva funcionalidad a código ya existente, tenemos la tendencia natural de escribir pruebas que consciente o inconscientemente sabemos que van a dar pocos problemas. Probamos entonces el mejor caso y que resuelve bien nuestro código: la prueba feliz viene a decirnos que nuestro código hace bien aquello para lo que lo hemos desarrollado. No obstante, si nos limitamos a escribir exclusivamente pruebas felices, estamos ignorando gran parte del objetivo de tener una solución respaldada por tests. Buscamos sólo pruebas felices porque en realidad percibimos el escribir pruebas como un mal que hay que asumir en lugar de un pilar fundamental y esencial en el desarrollo de un software de calidad y profesional.
El objetivo de escribir pruebas no es sólo el de tener un mecanismo por el que poder comprobar automáticamente que algo funciona ahora y seguirá funcionando en el futuro. Escribimos tests no sólo para la situación ideal (el camino feliz) sino que debemos desarrollarlos para comprobar todas aquellas situaciones incómodas en las que una funcionalidad particular se podría ver comprometida. Se nos olvida en ocasiones que los tests persiguen detectar errores, si nos quedamos con los casos más sencillos, seguramente estaremos ocultando bugs que tarde o temprano nos explotarán en las manos.
¿Cuándo es el momento más oportuno para detectar errores y problemas?, ¿cuando estamos precisamente desarrollando una nueva funcionalidad o cuando el software está ya en producción con uno o varios clientes usándolo?. La respuesta es más que obvia.
Recientemente he desarrollado un servicio de Windows para instanciar ciertos servicios web que emulan el comportamiento de un tipo de dispositivo. Se simula uno de estos dipositivos instanciando sus servicios web correspondientes en un puerto específico. Desarrollé como es lógico ciertas pruebas para garantizar que los web services se instancian bien para el puerto 8000, ¿y ya está?. Absolutamente no, ¿qué pasaría si al desplegar ese software en una máquina en producción ese puerto está ya siendo usado?. En este caso, las pruebas tienen que garantizar que somos correctamente notificados cuando se da esa circunstancia, que un error de este tipo no provoca un crash completo del servicio de Windows, etc. Si me hubiera quedado en la prueba feliz, seguramente habría terminado antes, pero con toda seguridad en el futuro habría tenido que dedicar muchísimo más tiempo a solucionar ese tipo de errores en producción y con un cliente insatisfecho...
Esto no es más que un ejemplo pero es que a veces no nos damos cuenta de la cantidad de esfuerzo y tiempo que nos podemos ahorrar detectando errores en producción sencillamente creando una batería correcta de tests en la fase de desarrollo. Pocas cosas hay que tranquilicen más en software que saber que tu producto está tan suficientemente probado que muy difícilmente se van a encontrar problemas en el despliegue del mismo.
Una ley del software viene a ser que cuanto más y mejor pruebes un software, mayor lo vas a rentabilizar, en el sentido de dedicar menos tiempo a depurar errores, el tener menos clientes reportando problemas, etc.
Tampoco es cuestión de crear el mayor número de pruebas porque sí sino de crear éstas con la calidad suficiente y cubriendo todos los posibles casos.
Este es un asunto que, me temo, solemos subestimar y es que no es trivial crear y saber desarrollar pruebas con la suficiente calidad; el problema es que en nuestra profesión muy a menudo debemos tener un carácter polifacético (lo que viene siendo tener que hacer de todo un poco); este no es un tema sencillo sino que el tester es un claro perfil de persona cualificada con ciertas aptitudes en su profesión, como bien indica este magnífico libro de Software Testing.