====== 04 - Introducción a las pruebas ====== Una **prueba** es un fragmento de código que compara el comportamiento real de la aplicación con el comportamiento esperado. Las pruebas automáticas se ejecutan sin intervención humana y permiten cambiar el código con confianza. ===== 1. Para qué sirven ===== * **Fiabilidad:** detectan errores antes de llegar a producción. * **Red de seguridad:** permiten refactorizar y añadir funcionalidad sin romper lo existente (**regresión**). * **Documentación ejecutable:** los casos de prueba muestran cómo se usa el código. * **Mejor diseño:** el código difícil de probar suele tener acoplamiento; probarlo empuja a separar responsabilidades. Una prueba que se ejecuta y pasa no garantiza la ausencia de errores; garantiza que **el comportamiento probado** funciona. ===== 2. Manual y automática ===== ^ Tipo ^ Cómo se ejecuta ^ Cuándo ^ | **Manual** | Una persona interactúa con la aplicación | Exploración, comprobación puntual | | **Automática** | El propio código de prueba se ejecuta en cada build | Regresión, validación continua | Las automáticas son la base del desarrollo moderno: se ejecutan miles de veces, en cada cambio, de forma idéntica. ===== 3. Tipos de pruebas ===== ^ Tipo ^ Qué comprueba ^ Ejemplo ^ | **Unitarias** | Una unidad de código aislada (clase, método) | Que un método calcula el total con descuento | | **Integración** | Que varias piezas colaboran correctamente | Que el service consulta el repository y devuelve el dato | | **Arquitectura** | Que el código respeta las reglas estructurales | Que la capa controller no depende de persistence | | **E2E** | El sistema completo, desde la interfaz, como un usuario | Registrar un usuario y ver su perfil en la aplicación real | ===== 4. La pirámide de pruebas ===== @startuml rectangle "E2E\n(pocas, lentas)" as e2e rectangle "Integración\n(algunas)" as int rectangle "Unitarias\n(muchas, rápidas)" as unit unit -[hidden]- int int -[hidden]- e2e @enduml ^ Nivel ^ Cantidad ^ Velocidad ^ Coste ^ | **Unitarias** | Muchas | Milisegundos | Bajo | | **Integración** | Menos | Segundos | Medio | | **E2E** | Pocas | Minutos | Alto | Cuanto más alto el nivel, más realista pero más lento y frágil. Por eso la base de la pirámide es ancha: la mayor parte del comportamiento se protege con unitarias rápidas, y los E2E cubren solo los flujos críticos. ===== 5. Una buena prueba ===== * **Determinista:** siempre produce el mismo resultado con las mismas entradas. * **Aislada:** no depende del orden de ejecución ni del estado de otras pruebas. * **Focada:** comprueba un comportamiento; si falla, el fallo indica dónde mirar. * **Rápida:** para poder ejecutarla con frecuencia. Las pruebas son código: se leen, se mantienen y se refactorizan como el resto. Una prueba lenta, aleatoria o acoplada al entorno deja de usarse, y deja de proteger.