====== 08 - TDD ====== **TDD** (*Test-Driven Development*, desarrollo dirigido por pruebas) invierte el orden habitual: la prueba se escribe **antes** que el código que la hace pasar. El ciclo tiene tres pasos, repetidos en bucles cortos. ===== 1. El ciclo ===== ^ Paso ^ Qué se hace ^ Resultado ^ | **Rojo** | Escribir una prueba del comportamiento nuevo y ejecutarla | Falla: el código no existe aún | | **Verde** | Escribir el código **mínimo** que hace pasar la prueba | Todas las pruebas pasan | | **Refactor** | Mejorar el diseño sin cambiar el comportamiento | Las pruebas siguen pasando | @startuml (*) --> "Escribir prueba (rojo)" "Escribir prueba (rojo)" --> "Ejecutar y verla fallar" "Ejecutar y verla fallar" --> "Escribir código mínimo (verde)" "Escribir código mínimo (verde)" --> "Ejecutar y verla pasar" "Ejecutar y verla pasar" --> "Refactorizar" "Refactorizar" --> "Ejecutar pruebas" "Ejecutar pruebas" --> "Escribir prueba (rojo)" : siguiente comportamiento "Ejecutar pruebas" --> (*) @enduml ===== 2. Ejemplo paso a paso ===== **Rojo:** la prueba describe el comportamiento que falta: @Test void refusesExpiredProduct() { Inventory inventory = new Inventory(); assertThrows(ExpiredProductException.class, () -> inventory.add("MILK-1", LocalDate.now().minusDays(1))); } Ejecutarla falla: ''Inventory'' no tiene ese método o no lanza la excepción. **Verde:** el código mínimo para pasarla: public void add(String code, LocalDate expiry) { if (expiry.isBefore(LocalDate.now())) { throw new ExpiredProductException(); } /* registrar el producto */ } **Refactor:** mejorar nombres, extraer una constante, simplificar. Las pruebas protegen cada cambio. ===== 3. Por qué funciona ===== * **Diseño guiado por uso:** la prueba obliga a pensar primero en la interfaz del código, desde el punto de vista de quien lo consume. * **Red de seguridad continua:** cada comportamiento queda protegido antes de que exista el código final. * **Feedback inmediato:** segundos entre el error y su corrección, no horas. * **Cobertura real:** no queda código sin probar porque cada línea nace de una prueba. ===== 4. Refactorización ===== **Refactorizar** es cambiar la estructura del código sin cambiar su comportamiento: extraer un método, renombrar, eliminar duplicación. Es el tercer paso del ciclo y depende de las pruebas: sin ellas, un refactor puede introducir errores invisibles. En la práctica, el asistente de IA puede proponer los cambios de refactorización; las pruebas son quienes comprueban que el comportamiento no ha cambiado. ===== 5. Cuándo conviene ===== ^ Encaja bien ^ Encaja peor ^ | Lógica de negocio con reglas claras | Código de interfaz, configuración | | Algoritmos y cálculos | Exploración y prototipos | | Corrección de errores: la prueba que reproduce el bug primero | Código efímero que se descartará | TDD no aumenta el número de pruebas escritas: las escribe antes, en pasos pequeños. El resultado es un código con la misma cobertura pero diseñado desde su uso.