TDD (Test Driven Development, o Desarrollo Guiado por Pruebas) es un proceso de desarrollo de software (aunque no veo ningún impedimento para extrapolarlo a cualquier otro proceso de desarrollo). Aunque aporta ventajas medibles y no es muy novedoso, en España ha tenido poco impacto y poca penetración.

Proceso de Desarrollo En Cascada
En realidad no supone un gran cambio respecto al proceso tradicional en cascada, pero el énfasis que pone en dos aspectos claves cambia la forma de ver el ciclo de desarrollo, al igual que una tilde o una coma pueden cambiar completamente el significado de un texto.
Una vez que el equipo de desarrollo y el cliente comprueban todo el valor que aportan a un producto, se preguntarán cómo han podido vivir antes. Pero para llegar a este estado se debe contar con el apoyo claro de la dirección del equipo de desarrollo.
Primero las pruebas [1]

TDD - Core
Tradicionalmente primero se desarrolla y luego se prueba. Este proceso propone intercambiar el orden las cajitas de desarrollo y pruebas para que las pruebas guíen el desarrollo (incluso hay quien dice que deben guiar el diseño) :
- Primero especificar y desarrollar pruebas que debe superar el producto.
- Después se desarrolla. Este paso no se da por finalizado hasta que se superan todos los test. Esta es la razón por la que se dice que las pruebas guían el desarrollo.
- Finalmente se refactoriza (cambiar la estructura interna de un sistema sin afectar a sus funcionalidades) tanto las pruebas como el código para mejorar el diseño interno. Al igual que el paso anterior, esta tarea no se da por completada hasta que se superen todos los test.
Se consigue mejorar la comunicación entre equipos, aumentar la comprensión de lo que realmente se debe desarrollar y al automatizar las pruebas se reduce muy significativamente el tiempo dedicado a pruebas manuales (tanto por el equipo de desarrollo como por el cliente al validar los entregables) a la vez que se aumenta la confianza en el producto.
Entregas frecuentes [2]

Waterfall vs Iterative Waterfall
Por otro lado aconseja la repetición de ciclos de desarrollo muy cortos. En cada iteración (o entrega) se parte de un estado estable y confiable (el código supera todas las pruebas automáticas) y finalizamos en otro estado estable y confiable.
También aporta grades beneficios a nivel global del proyecto. Si debemos especificar menos requisitos y partimos de un prototipo podremos ser más específicos y rigurosos, y las entregas continuas facilitan el control del desarrollo (garantizando que la comprensión del producto es la correcta y mejorando el diseño interno) y en la fase de explotación aumentan el valor del producto reduciendo el tiempo de entrega.
Ajustando los parámetros : cobertura
El precio a pagar por la utilización de este proceso es que desarrollar pruebas significa que hay más código que mantener, más tiempo de desarrollo inicial, más código que probar (las pruebas no tienen por qué estar libre de errores, desarrollamos pruebas para las pruebas? Y también pruebas para las pruebas de las pruebas?…). También es posible encontrar pruebas que no cubran efectivamente el código y/o no han evolucionado mientras el código que cubren sí.
Por tanto se puede recuperar con creces la inversión en el tiempo desarrollo de las pruebas o lastrar el proyecto. Así, la cobertura de los test, es decir el código que se cubre efectivamente con un test, resulta una decisión crucial para optimizar el proceso y maximizar el ROI de aplicar este proceso.
Sobre la cobertura de los test hay opiniones para todos los gustos, incluso propuestas tan disparatadas como perseguir el 100% de cobertura o valorar la calidad de tu código en función del % de código que está cubierto por test. La opción mayoritaria, que es la que yo recomiendo, es cubrir con test hasta que nuestra confianza en el sistema sea aceptable. Cómo?
- Recomiendo definir un criterio de validación para cada funcionalidad, automatizar estas pruebas de aceptación así como las posibles APIs (puntos de entrada de terceros a nuestro sistema).
- Recomiendo utilizar los datos que se utilizaron para definir los requisitos como Datos de Entrada para alimentar las pruebas. Para ello se pueden utilizar Hojas de Cálculo y/o Bases de Datos. Las Hojas de Cálculo son fácilmente entendibles y mantenibles por los propios usuarios, se pueden adjuntar como anexos al contrato del proyecto y pueden ser leídos por un programa informático.
- Prefiero probar el negocio que los servicios o la persistencia ya que el negocio no puede funcionar si no funciona correctamente el resto.
No más, no menos. Más significa más código a mantener y evolucionar (y posibilidades de error) sin que nos aporte valor, simplemente tardaremos un poco más de tiempo en encontrar exactamente el fallo en un test que no se pasa. Menos significa que nuestro sistema no es confiable.
Para profundizar…
De mi cosecha añadiría también un tercer cambio de paradigma o énfasis. El artefacto entregable es un sistema software (como tradicionalmente lo hemos visto) pero también es un producto (como realmente lo ve un usuario): es importante que el desarrollador lo entienda también como un producto para maximizar el valor del sistema para el cliente y poder reutilizar los máximos componentes posibles.
Los seguidores de TDD recomiendan desarrollar siguiendo los principios KISS (“Keep It Simple, Stupid”, lo simple es bello, efectivo y eficaz) y YAGNI (“You Ain’t Gonna Need It”, no lo vas a necesitar). Yo recomiendo utilizar KISS para todo en esta vida, y YAGNI con mucho cuidado, ya que en ocasiones no seguirlo resulta útil para detectar fallos en el diseño: estás seguro de que no lo vas a necesitar?
[1] Imagen vista en nilclass.
[2] Imagen vista en Agile101. Para ampliar información, consultar The Difference Between Waterfall, Iterative Waterfall, Scrum and Lean Software Development (In Pictures!).