Qué es exactamente un test inestable

Un test inestable, o flaky, es el que produce resultados distintos en ejecuciones sucesivas sin que hayan cambiado ni el sistema bajo prueba ni el propio test. No es un test lento, ni uno que falla siempre por un defecto conocido: es uno cuyo resultado no es determinista.

Su coste no está en el tiempo que hace perder, sino en lo que destruye: la confianza. En cuanto un equipo aprende que un fallo rojo "probablemente sea el test", empieza a reejecutar sin mirar, y el día que el rojo era un defecto real llega a producción sin que nadie lo haya leído.

Causas por orden de probabilidad

  1. Sincronización: el test actúa antes de que la aplicación esté lista. Es la causa número uno, y se manifiesta más en máquinas de integración continua, que suelen ir más lentas que el portátil donde se escribió la prueba.
  2. Datos compartidos: dos pruebas usan el mismo usuario, el mismo pedido o el mismo saldo. Al ejecutarse en paralelo, o en otro orden, se pisan entre ellas.
  3. Dependencia del orden: una prueba deja un estado del que otra depende sin decirlo. Funciona en la secuencia habitual y se rompe en cualquier otra.
  4. Entorno: servicios que tardan en levantar, versiones de navegador o driver que cambian, discos llenos, husos horarios, idiomas del sistema.
  5. Dependencias externas: servicios de terceros con cuota, latencia variable o disponibilidad irregular.
  6. Aleatoriedad y tiempo: datos generados al azar sin semilla fija, o lógica que depende de la fecha y falla el día uno de mes o en el cambio de hora.

El diagnóstico, paso a paso

  1. Mide la tasa de inestabilidad por prueba: qué porcentaje de ejecuciones falla sobre el mismo commit. Sin ese dato no puedes priorizar.
  2. Ejecuta la prueba sospechosa veinte veces en aislamiento. Si nunca falla, el problema es de interacción con otras pruebas: datos u orden.
  3. Ejecútala en paralelo con el resto. Si falla ahí, ya tienes localizada la colisión.
  4. Revisa cada espera del test. Cualquier pausa fija es sospechosa por definición.
  5. Comprueba las evidencias del fallo: captura, log y petición. Si no las tienes, ese es el primer arreglo, porque sin ellas cada diagnóstico empieza de cero.

Arreglos que funcionan

CausaArreglo correctoParche que la esconde
SincronizaciónEspera explícita por condición observableAumentar el sleep
Datos compartidosDatos propios por ejecución, creados y limpiados por el testEjecutar en serie para que no colisionen
Dependencia del ordenSetup y teardown completos en cada pruebaFijar el orden de ejecución
EntornoEntorno reproducible con versiones fijadas y comprobación de arranqueReejecutar hasta que salga verde
Servicio externoDoble de prueba o virtualización, con contrato verificado aparteReintentos indefinidos

Los reintentos automáticos merecen un párrafo propio. Son útiles como medida temporal y trazada: reintento contado, marcado en el informe y con fecha de revisión. Convertidos en política permanente son un mecanismo para ocultar defectos reales del producto, incluidos los de concurrencia, que son precisamente los que más caros salen en producción.

La cuarentena bien hecha

Cuando una prueba inestable bloquea la pipeline y no hay tiempo de arreglarla en el momento, la respuesta correcta es la cuarentena: se saca del conjunto que corta la entrega, pero se sigue ejecutando y midiendo, se le asigna un responsable y se le pone una fecha límite. Sin esas tres condiciones, la cuarentena es un cajón donde las pruebas van a morir.

Y conviene vigilar el tamaño de ese cajón como una métrica más: si crece mes a mes, el problema no son las pruebas, es que la solución de automatización se está degradando más rápido de lo que se mantiene.

Pon a prueba lo que acabas de leer

El simulador tiene 478 preguntas con explicación razonada, y los apuntes por capítulo resumen el syllabus entero. Todo gratis y sin registro.

Seguir leyendo