La mayoría de los equipos no tienen un problema de "falta de pruebas". Hay un problema con las pruebas mal diseñadas.
Empiezan con buenas intenciones. Alguien escribe una prueba, luego otra, y al cabo de unos meses hay un conjunto con cientos de casos. El problema aparece cuando esta suite empieza a tardar veinte minutos en ejecutarse, se rompe por algún cambio trivial y ya nadie confía en el resultado rojo. La reacción natural es desactivar la prueba de "siempre falla". A partir de entonces, la suite se convierte en teatro.
Esta guía es sencilla: antes de discutir qué herramienta utilizar, decida la arquitectura de sus pruebas. Es esta decisión la que separa una suite que protege al equipo de otra que lo ralentiza.
Por qué la arquitectura está antes que la cobertura
La cobertura es una métrica fácil de medir y fácil de engañar. Puede tener una cobertura del 90% probando captadores y definidores, sin proteger ninguna regla comercial importante.
Lo que realmente sustenta la velocidad es la forma en que están organizadas las pruebas: qué prueba cada nivel, qué tan rápido corren, qué tan aislados están y con qué claridad señalan qué se rompió. Esta es una decisión arquitectónica, no una decisión cuantitativa.
Lo considero infraestructura. No se escala un sistema apilando servidores aleatoriamente; define capas, responsabilidades y contratos. Lo mismo ocurre con las pruebas. Sin diseño, la suite crece como deuda, no como activo.
La pirámide sigue siendo el punto de partida.
La pirámide de pruebas sigue siendo el modelo mental más útil para empezar. La base son las pruebas unitarias: muchas, rápidas, aisladas. En el medio, las pruebas de integración, que comprueban si las piezas se comunican entre sí. En la parte superior, algunas pruebas de un extremo a otro, que ejercitan el flujo de usuarios.
La regla general es simple. Cuanto más arriba en la pirámide, más cara y lenta será la prueba, y más frágil. Por eso la parte superior debe ser estrecha. Un equipo que invierte la pirámide, con decenas de pruebas de interfaz y pocas pruebas unitarias, tendrá una suite lenta e inestable.
El error más común aquí es tratar la pirámide como un dogma. En sistemas que están muy orientados a la integración, como las API que organizan servicios, por ejemplo, tiene sentido espesar la capa de integración. El formato importa menos que el principio: llevar la verificación al nivel más barato que aún dé confianza.
Decisiones que definen la arquitectura
Algunas opciones tienen un impacto desproporcionado en la salud de la suite. Vale la pena resolverlos temprano.
El primero es qué aislar. Las pruebas unitarias deben ejecutarse sin banco, sin red, sin reloj real. Cuando necesitas subir la mitad de un sistema para probar una función, el problema no es la prueba, es el acoplamiento del código. La prueba es sólo informativa.
El segundo es cómo abordar las dependencias externas. Los simulacros y los talones lo aceleran, pero mienten: prueban lo que usted cree que hace la dependencia, no lo que hace. Así que reservo las pruebas de integración reales para límites críticos, pago, autenticación, persistencia y uso dobles con moderación para el resto.
El tercero es donde viven las pruebas. Manténgalos cerca del código que verifican. Las suites en repositorios separados casi siempre se pudren porque cambian a un ritmo diferente al del código de producción.
La velocidad es una característica de la suite.
Una suite lenta es una suite que será ignorada. Si ejecutar todo lleva media hora, el desarrollador solo ejecutará una parte, o nada en absoluto, y solo descubrirá el problema en la cinta transportadora de CI, demasiado tarde.
El objetivo práctico es que la capa de unidad se ejecute en segundos, localmente, durante el desarrollo. Esto requiere disciplina: pruebas paralelizables, sin dependencia del estado compartido, sin sleep para "esperar" algo. Las esperas fijas son la mayor fuente de lentitud e inestabilidad en las suites reales.
En CI, separe por etapa. Ejecute la unidad primero, falle rápidamente y solo después pase a la integración y de un extremo a otro. No tiene sentido dedicar diez minutos a una prueba de interfaz si ya se incumple una regla básica.
El verdadero enemigo: las pruebas intermitentes
Si hay un solo elemento que destruye la confianza en una suite, es la prueba que a veces pasa y otras falla sin que nada cambie. Es peor que no tener ninguna prueba, porque le enseña al equipo a ignorar el rojo.
Las pruebas intermitentes casi siempre surgen de tres fuentes: dependencia del tiempo, dependencia del orden de ejecución y estado compartido entre casos. Resolver esto es una obra de arquitectura, no de paciencia. Cada prueba debe configurar y limpiar su propio escenario, sin asumir nada sobre lo que se ejecutó antes.
Trato las pruebas intermitentes como un incidente, no como ruido. Cuando aparece uno, lo arreglo o lo elimino. Mantener una prueba poco confiable en la suite contamina a todas las demás.
¿Quién garantiza la calidad de la suite?
Aquí viene la visión de gestión que muchos equipos ignoran. El código de prueba es código. Necesita revisión, refactorización y propiedad. Una suite abandonada se degrada al mismo ritmo que cualquier otro sistema sin mantenimiento.
En los equipos que dirijo, la regla es que las pruebas son parte de la definición de hecho, no es una tarea separada que se lleva al final del sprint. Y el estado de la suite (tiempo de ejecución, tasa de fallas intermitentes) se incluye como una métrica de ingeniería, junto con otras que monitoreamos.
En el contexto público y en productos que tratan con datos sensibles, esto adquiere otro peso. Una suite confiable es parte de lo que le permite cambiar un sistema crítico sin tener que esperar a que nada se rompa. Esto es gobernanza, no capricho técnico.
Empiece poco a poco, pero empiece dibujando.
Si su suite aún es pequeña, este es el momento más económico para lograr la arquitectura correcta. Definir los niveles, establecer que las pruebas unitarias no toquen la infraestructura, exigir que cada prueba esté aislada y tratar la velocidad como un requisito.
Si la suite ya es grande y dolorosa, no intente reescribirlo todo. Detener primero el sangrado: eliminar los intermitentes, separar las etapas en el CI y proteger con nuevas pruebas sólo lo que cambia con frecuencia. El resto lo vas mejorando poco a poco.
Hoy en día no existen pruebas automatizadas que demuestren que el código funciona. Existen para darte el coraje de cambiarlo mañana. Una buena arquitectura de pruebas es, en esencia, un seguro contra el miedo a que el sistema evolucione.
Si su equipo ya tiene pruebas pero ha perdido la confianza en ellas, vale la pena revisar la arquitectura antes de escribir otro caso. Tengo otros textos en el blog sobre calidad e ingeniería de software, y si este es un problema real en su organización, este es el tipo de conversación que vale la pena.
Lea también
- Arquitectura de prueba automatizada: los pasos esenciales para configurar desde cero
- Pruebas de regresión: seguro contra romper lo que ya funcionó
- Ciclo de pruebas de software: tendencias y una guía rápida para líderes
- Pruebas automatizadas: por qué el código no probado es deuda
- Rendimiento del software: lo que enseñan casos reales sobre la calidad
- Pruebas automatizadas: arquitectura y fundamentos