Test-driven development: así funciona este método

A medida que aumenta la complejidad de los programas informáticos, la metodología ágil del test-driven development (TDD)se vuelve cada vez más popular. No es de extrañar, ya que el TDD permite a los programadores asegurarse de que no hayan quedado lagunas en el diseño de software antes de escribir el código fuente. De esta manera, no solo aumenta considerablemente la calidad del software final, sino que también se reducen los costes de mantenimiento.

El desarrollo guiado por pruebas se usa, entre otros ámbitos, en la programación extrema o extreme programming, caracterizada por las reviews, los test y el diseño y rediseño constantes. El test-driven development también se ajusta a un ciclo de desarrollo, que debe ser respetado para que la implementación resulte eficaz.

¿Qué es el test-driven development?

Hace mucho que existen métodos variados para poner a prueba la calidad de los programas. Ya en los inicios del desarrollo de software, la funcionalidad de los programas era evaluada en los departamentos de calidad por testers independientes. Por aquel entonces, el desarrollo del software en sí y los procedimientos de prueba se consideraban cuestiones independientes. Esta percepción cambió cuando Kent Beck, el desarrollador estadounidense creador del extreme programming, lanzó el concepto test first, que le dio la vuelta al orden de las tareas: en lugar de escribir primero el código fuente y luego ponerlo a prueba, el equipo de desarrolladores escribe primero los test y luego usa los casos de prueba para escribir e implementar el código de la mejor manera posible.

Si no se tienen muchos conocimientos de desarrollo de software, este proceso puede sonar contraintuitivo, pero efectivamente tiene mucho sentido y da mejores resultados. Mientras que los métodos de prueba convencionales realizados a posteriori aplican un modelo en cascada o en V, los procesos del TDD se desarrollan en forma de ciclo. Más concretamente, primero se identifican a propósito los casos de prueba que suelen fallar, y luego se redacta únicamente el código necesario para superar los test. Luego se refactorizan los componentes: manteniendo las funciones, se amplía o se reestructura el código fuente, según sea necesario.

¿Cómo funciona exactamente el test-driven development?

El test-driven development se orienta según los resultados de los casos de prueba definidos por los desarrolladores. Su estructura cíclica garantiza que el código se transmita al sistema productivo únicamente cuando se hayan cumplido todos los requisitos del software. En otras palabras, los elementos del código se refactorizan y se vuelven a poner a prueba tantas veces como sea necesario, hasta que el test ya no dé errores. Esta estrategia permite enriquecer el software poco a poco con nuevas funciones, redactando nuevo código fuente tras cada test superado. Por este motivo, el TDD se considera un modelo incremental de desarrollo de software.

Cada test no suele tardar más de unos segundos o minutos en recorrer el ciclo, de manera que los resultados pueden observarse rápidamente en el código productivo. Para que las repeticiones puedan llevarse a cabo sin esfuerzo añadido, son necesarios una herramienta y un framework de TDD. Los desarrolladores usan, por lo general, herramientas de automatización del build,como CruiseControl o Jenkins, que permiten integrar componentes en el código fuente de forma continua y sin fallos. Otros frameworks y tools populares en el desarrollo con Java son JUnit, Maven y Ant. Por regla general, los test se redactan siempre en el mismo lenguaje de programación que el código fuente. Para PHP existen, entre otras herramientas, Ceedling y CMock.

¿Y cómo se desarrollan exactamente los test? El ciclo que siguen los programadores en el test-driven development también recibe el nombre de red-green-refactor y describe cada una de las fases que deben cumplirse para alcanzar una mayor eficiencia:

  1. Fase roja (red phase): en esta fase hay que ponerse en los zapatos del usuario, que quiere poder usar el código de forma sencilla. Se redacta, por lo tanto, un test que contenga componentes que aún no hayan sido implementados, para luego decidir qué elementos son realmente necesarios para que el código funcione.
  2. Fase verde (green phase): suponiendo que el test falle y se marque en rojo, se adopta entonces el papel de programador y se intenta encontrar una solución simple.Es muy importante redactar únicamente la cantidad de código que sea necesaria. El código redactado se integra luego en el código productivo, de forma que el test quede marcado en verde.
  3. Refactoring: en este paso, el código productivo se pasa a limpio y se perfecciona su estructura. Podría decirse que ahora se completa y reestructura de manera que resulte elegante y comprensible para los desarrolladores. Entre otras cosas, se eliminan los duplicados en el código, y se vuelve más profesional.

Hay que tener en cuenta que las tareas no se solapen entre ellas, es decir, que no se redacten test en las fases 2 y 3 ni se escriba código productivo en las fases 1 y 3.

¿En qué se diferencia el TDD de otros métodos de prueba?

El test-driven development es una metodología de diseño de software que se basa en test o pruebas para guiar el proceso. Al contrario de lo que ocurre en metodologías que posponen los test a un punto ulterior, los casos de prueba en TDD se realizan al inicio del proceso de diseño. Los test que se utilizan en esta metodología difieren en cuanto a propósito y alcance: el más sencillo es el test de módulos ounit test. Con él se prueban los componentes individuales de un programa informático. Otros test más complejos son las pruebas funcionales y de integración, que examinan la interacción entre las distintas partes del sistema y la funcionalidad del software en conjunto.

A partir del TDD se desarrolló, hace unos años, el behavior-driven development (BDD) o, en español, el desarrollo guiado por comportamiento. Esta metodología no se guía inicialmente por la adecuación del código, sino por el comportamiento que desea observarse en el software. Una de las ventajas de esta estrategia es que no requiere conocimientos especializados de codificación para especificar los casos de prueba deseados, lo cual permite incorporar en el proceso de desarrollo a gestores de calidad y a otras partes interesadas. De forma general, puede decirse que el BDD es el mejor método a la hora de diseñar pruebas, mientras que el TDD da como resultado una arquitectura más limpia.

La tabla siguiente resume las ventajas e inconvenientes del desarrollo guiado por pruebas:

Ventajas Inconvenientes
El software resultante es de alta calidad y tiene menos bugs. Requiere conocimientos previos de codificación y mayor tiempo de aprendizaje.
La arquitectura del sistema y el código productivo son fáciles de comprender y están bien estructurados. Solo comprueba la adecuación del código, no la funcionalidad del software.
La identificación de fallos es rápida y el trabajo de mantenimiento se reduce. En algunos casos ha de ir acompañado de otros métodos de prueba.
La eliminación de redundancias en el código evita el overengineering, es decir, la complejidad innecesaria del producto.  

Aunque los distintos métodos de prueba pueden implementarse uno a uno, aplicando una combinación de métodos basados en pruebas y en comportamiento se obtiene un software de mayor calidad, que también proporciona mayor satisfacción al cliente.