4.5Tests automatizados con PHPUnit
Lo esencial en 30 segundos
- Tests = código que prueba el código : PHPUnit (vía Composer), aserciones (
assertEquals,assertTrue…) que fallan si lo real ≠ lo esperado. - 3 niveles : unitarios (función aislada), integración (con la base), funcionales (como un usuario) —
./vendor/bin/phpunitlos lanza todos. - Reflejo de Riad : probar primero la lógica de negocio crítica, relanzar tras cada cambio — la no regresión que libera.
Minicaso seguido — Riad blinda sus precios antes de la promo
En vísperas de las promos, Riad teme que un descuento rompa sus precios en Constantine : escribe su primer test PHPUnit sobre prixTTC, añade los casos límite (cero, tasa nula, cesta vacía), y luego relanza toda la suite tras cada retoque. Cuando un colega modifica el cálculo, el test se pone en rojo ANTES de la puesta en línea. Último hito del hilo : del prototipo que « funciona » a la aplicación pro que demuestra.
Último episodio del caso 4.1-4.4 — Riad cierra el nivel : arquitecturar, equipar, exponer, fiabilizar.
1. PHPUnit y las aserciones
Probar a mano es fastidioso, incompleto y no repetible : escribimos código que PRUEBA el código, relanzable a voluntad. En PHP, la referencia es PHPUnit (instalado vía Composer, lanzado por ./vendor/bin/phpunit). Un test verifica que una entrada da la salida ESPERADA vía aserciones — assertEquals($attendu, $resultat), assertTrue(...), assertNull(...) — que fallan si la realidad difiere. Tests organizados en clases y métodos, ejecutados en masa con informe de pasados/fallidos. Tres niveles : unitarios (función/clase aislada), integración (varias partes, p. ej. con la base), funcionales/de extremo a extremo (como un usuario).
2. Los beneficios y el TDD
Los beneficios : CONFIANZA (sabemos, no creemos), NO REGRESIÓN — el mayor — (relanzar tras cada cambio avisa enseguida si un retoque rompe lo que funcionaba), DOCUMENTACIÓN (comportamiento esperado, ejecutable y al día), MEJOR DISEÑO (el código testeable está mejor dividido), detección TEMPRANA (en dev, no en prod). Laravel y Symfony integran PHPUnit con herramientas dedicadas (bases de test, peticiones HTTP simuladas). El TDD escribe los tests ANTES del código (el test define lo esperado, el código lo hace pasar) — disciplina que mejora el diseño. Riad empieza pequeño : lógica crítica primero, no 100 % de entrada.
🔎 Ejemplo concreto — 🔎 Ejemplo concreto — Primer test de precio TTC
El primer test de Riad, con las API reales de PHPUnit :
prixTTC(100, 0.20) → esperado 120.0 (assertEquals)
prixTTC(0, 0.20) → esperado 0 (caso límite)
Lanzar → ./vendor/bin/phpunit → OK (2 tests, 2 aserciones)
Retoque → relanzar → verde = nada roto
Lectura : una entrada, un esperado, una aserción — y luego el bucle.
Lección : los casos límite atrapan los bugs que la demo no ve.
Vocabulario de la sección
- Tests automatizados / PHPUnit
- Código que PRUEBA vuestro código (relanzable a voluntad) en lugar de verificar a mano. PHPUnit es el estándar PHP (vía Composer).
Ejemplo sencillo: Riad lanza ./vendor/bin/phpunit y obtiene su informe en segundos.
Lo que no es: una verificación manual única en el navegador.
Reflejo: todo comportamiento crítico merece su test.
- Aserciones
- Verificaciones del test : assertEquals(esperado, resultado), assertTrue, assertNull… — fallan si lo real ≠ lo esperado.
Ejemplo sencillo: Riad afirma assertEquals(120, prixTTC(100, 0.20)).
Lo que no es: un echo « parece bueno » sin comparación estricta.
Reflejo: esperado primero, real después, mensaje claro.
- Niveles de tests
- Unitarios (aislado), integración (varias partes, p. ej. con la base), funcionales/de extremo a extremo (como un usuario).
Ejemplo sencillo: Riad prueba prixTTC en unitario, el pedido con su base en integración.
Lo que no es: un solo gran test que mezcla todo.
Reflejo: pirámide : muchos unitarios, pocos de extremo a extremo.
- Beneficios de los tests
- Confianza, NO REGRESIÓN (detectar lo que un cambio rompe), documentación, mejor diseño, detección temprana.
Ejemplo sencillo: La suite de Riad atrapa un descuento roto antes de la promo.
Lo que no es: descubrir la rotura por un ticket de cliente en producción.
Reflejo: suite verde exigida antes de cada entrega.
- TDD (Test-Driven Development)
- Escribir los tests ANTES del código (el test define lo esperado, el código lo hace pasar) ; disciplina que mejora el diseño.
Ejemplo sencillo: Riad escribe el test de descuento antes de la función, luego programa hasta el verde.
Lo que no es: programar al azar y luego probar para « validar » después.
Reflejo: rojo → verde → refactor : el ciclo TDD.
En la práctica — En la práctica — Fiabilizar su código con tests
- Instalad PHPUnit (vía Composer) y escribid un primer test unitario de una función (entrada → esperado, assertEquals…).
- Lanzad con ./vendor/bin/phpunit, leed el informe ; añadid casos límite y entradas inválidas.
- Escribid un test de integración (funcionalidad + base) ; con framework, usad las herramientas de test integradas.
- Relanzad tras cada cambio (no regresión) y probad el TDD (test ANTES del código).
Guion listo para decir — anunciar la suite verde (30 s)
« Soy Riad : nuestros cálculos críticos están cubiertos por PHPUnit — unitarios, casos límite e integración base. Cada retoque relanza la suite : verde, entregamos ; rojo, corregimos antes de la prod. »
Para decir antes de cada entrega ; mostrad la suite verde.
Modelo copiar-pegar — test PHPUnit (código probado)
assertEquals(120.0, prixTTC(100, 0.20));
}
public function testCasLimites(): void {
$this->assertEquals(0.0, prixTTC(0, 0.20));
$this->assertEquals(100.0, prixTTC(100, 0.0));
$this->assertTrue(prixTTC(50, 0.20) > 50);
}
}
// Lanzar : ./vendor/bin/phpunit PrixTest.php
Primer paso
Un solo test sobre el cálculo crítico : valor inmediato, hábito instalado.
Lógica de riesgo
Como Riad : cálculos, reglas de negocio, casos límite e inválidos — donde los bugs cuestan caros.
Con framework
Bases de test y peticiones HTTP simuladas de Laravel/Symfony para la integración.
Equipo que crece
Suite verde exigida antes de merge : la no regresión se vuelve un ritual colectivo.
.env.testing fuera de Git) y mantener los datos personales fuera de los juegos de test. Contenido pedagógico, ejemplos con datos ficticios.✓ Buenas prácticas
- Probar la lógica crítica con prioridad.
- Relanzar tras cada cambio.
- Probar el TDD en una pequeña función.
✗ Errores frecuentes
- Creer que « funciona » dispensa de probar.
- Apuntar al 100 % de cobertura de entrada.
- Solo probar a mano, una vez.
Puntos clave
- TESTS AUTOMATIZADOS (PHPUnit, estándar PHP) : código que PRUEBA el código. ASERCIONES (assertEquals…) si lo real ≠ lo esperado.
- NIVELES : UNITARIOS (aislado), INTEGRACIÓN (con base), FUNCIONALES (como un usuario).
- BENEFICIOS : CONFIANZA, NO REGRESIÓN (relanzar tras cada cambio — el mayor), documentación, DISEÑO.
- Los frameworks integran PHPUnit. TDD = tests ANTES del código. INDISPENSABLE en prod — separa prototipo y app PRO.
Desafío 48h — aplicad mañana
Escribid 2 tests PHPUnit sobre vuestra función más crítica (1 caso normal + 1 caso límite) y relanzad tras 1 retoque.
- Puedo explicar PHPUnit, aserciones, niveles.
- Sé lanzar la suite y leer el informe.
- Tengo 2 tests verdes sobre mi lógica crítica.
Preguntas frecuentes
Los tests parecen una pérdida de tiempo cuando « ya funciona » : ¿por qué probar?
Porque « funciona » solo vale para los casos verificados a mano, hoy. Mañana, cada cambio arriesga una regresión silenciosa — sin tests, habría que re-verificar todo a mano, lo que nunca hacemos. Los tests aportan confianza (sabemos), no regresión (aviso inmediato), documentación viva del comportamiento, mejor diseño (lo testeable está mejor dividido) y detección temprana — infinitamente más barata que en producción.
¿Cómo empezar sin verse superado — qué probar con prioridad?
Progresivo, no 100 % de entrada : lógica de negocio crítica (cálculos, reglas — donde un bug cuesta caro), código complejo/de riesgo o que se rompe a menudo, casos límite y entradas inválidas (cero, extremos, vacíos — donde se esconden los bugs), código reutilizado (un bug se propaga por todas partes). Menos prioritario al inicio : trivial (getters), presentación pura. Método : Arrange-Act-Assert — preparar, actuar, verificar.
¿Cuál es el beneficio principal de los tests automatizados?