====== 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.