No todos los tests tienen el mismo valor. Comparto mi pirámide de testing pragmática.
La trampa del 100% coverage
He visto proyectos con 95% de coverage que estaban llenos de bugs. El problema: tests que verifican que un método fue llamado, no que el comportamiento es correcto. Un test que solo verifica que repository.save() fue invocado no te dice nada útil. Un test que verifica que al crear un expediente se generan los documentos correctos con los datos correctos, eso sí tiene valor.
Tests de contrato para microservicios
En SAGCOM 2.0, cada microservicio tiene contratos definidos (OpenAPI). Los tests de contrato verifican que productor y consumidor están de acuerdo en la estructura de datos. Cuando evaluación-médica cambia su API, los tests de contrato de sesiones fallan antes de llegar a producción.
Integration tests con Testcontainers
Los tests contra mocks de base de datos son mentira. Testcontainers levanta un PostgreSQL/SQL Server real en Docker durante el test. Si tu query funciona contra la base real en el pipeline, funcionará en producción. Esto detecta problemas que los mocks jamás encontrarían: constraints, tipos de datos, colaciones.
Mutation testing con PIT
PIT modifica tu código (mutaciones) y verifica si tus tests detectan el cambio. Si cambias un > por < y ningún test falla, tu test no está verificando nada útil. En los servicios críticos de SAGCOM, exigimos un mutation score mínimo del 70%.
Mi pirámide pragmática
- ▹ Base: Unit tests para lógica de negocio compleja (domain layer).
- ▹ Medio: Integration tests con Testcontainers para repositorios y APIs externas.
- ▹ Cima: E2E tests solo para los 5-10 flujos críticos del negocio.