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