Un filtro mejor para las pruebas automatizadas de UI

Ordena los flujos según cuánto tiempo pasaría un fallo sin que nadie lo notara, no según lo importantes que sean. Una exportación, una invitación, una página de configuración, un resumen programado. Cada uno le importa a alguien y ninguno tiene una multitud mirando, así que una regresión se queda ahí un mes.

Segundo filtro: con qué frecuencia cambia el flujo. Una pantalla que se rediseña cada sprint costará más en mantenimiento de lo que devuelve. Cúbrela cuando se estabilice.

Los tres costos

Selectores

  • Un rediseño que no cambia nada funcional pone la suite en rojo.

  • Donde se va en realidad la mayor parte del tiempo de mantenimiento.

Esperas

  • Los retardos fijos son lentos y aun así inestables. Las esperas correctas necesitan saber qué esperar.

  • La mayor parte de la inestabilidad viene de aquí.

Cobertura escrita a mano

  • Cubres lo que alguien escribió, es decir, los flujos interesantes y no los que se rompen.

Los dos primeros se resuelven con disciplina. El tercero es estructural: la cobertura escrita a mano está limitada por el tiempo de quien la escribe, y ese tiempo no crece.

Tres hábitos que más ahorran

  • Ancla en atributos estables. Un atributo dedicado a pruebas en lugar de una ruta CSS. Esto por sí solo elimina la mayoría de las roturas por rediseño.

  • Espera por estado, nunca por tiempo. Espera al elemento o a la respuesta. Un retardo fijo es a la vez lento y poco fiable.

  • Verifica lo que confirmaría una recarga. Un toast de éxito no es prueba de que algo se haya guardado.

Por qué las suites terminan borradas

No porque no encuentren nada. Porque la proporción entre fallos reales y fallos de mantenimiento empeora tanto que la gente deja de leer los resultados. Cuando una compilación en rojo significa «probablemente un selector» y no «probablemente un bug», la suite ha dejado de funcionar aunque siga ejecutándose.

Proteger esa proporción es el trabajo de verdad, y tiene más que ver con cómo se expresan los pasos que con cuántas pruebas tienes.

Cobertura que no depende del tiempo de quien la escribe

Los pasos expresados como intenciones sobreviven a los cambios cosméticos, y la cobertura generada a partir del producto, y no de la memoria de alguien, incluye flujos que nadie habría escrito. Esa es la parte del costo que la disciplina no puede arreglar.

Terminal

npm install -g @testsprite/testsprite-cli
testsprite setup

El panel cubre lo mismo para quien no quiera una instalación local, y el conjunto completo de comandos vive en el repositorio del CLI.

El tamaño de suite que sigue siendo útil

Hay un tamaño a partir del cual una suite de navegador empieza a costar más de lo que devuelve, y es más pequeño de lo que la mayoría de los equipos espera.

La limitación no es el tiempo de ejecución, es la atención. Una suite de treinta flujos produce fallos que alguien investiga. Una de trescientos produce una lista diaria, y las listas se clasifican por prioridad en lugar de leerse. En cuanto empieza esa clasificación, la prueba marginal añade ruido en lugar de cobertura, por bien escrita que esté.

Así que la pregunta útil al añadir una prueba no es si el flujo importa. Es si investigarías el fallo de esa prueba un viernes por la tarde. Si la respuesta honesta es que la volverías a ejecutar y seguirías adelante, la prueba ya es ruido y escribirla empeora la suite.

Ejecútalo en cada cambio

El disparador importa más que el mecanismo. Apuntarlo a tu evento de despliegue hace que cada cambio se revise sin que nadie tenga que decidirlo; la GitHub App lo hace desde el panel, y un paso de GitHub Actions lo hace desde dentro de tu flujo de trabajo.

Dónde TestSprite cambia las cuentas

El tercer costo, la cobertura limitada por el tiempo de quien la escribe, es el que la disciplina no puede arreglar, y es el que TestSprite elimina. Los casos se generan a partir de tu producto y se refinan en lenguaje sencillo, así que los flujos silenciosos quedan cubiertos sin que nadie tenga que encontrar una tarde para escribirlos.

Los dos primeros costos mejoran como efecto secundario. Los pasos se guardan como intenciones y no como rutas por el DOM, así que un rediseño que mueve un botón no pone la suite en rojo, y la espera se gestiona en lugar de ajustarse prueba por prueba. En esos dos se va la mayor parte del tiempo de mantenimiento.

Lo que eso protege es el número que decide si una suite sobrevive: el porcentaje de compilaciones en rojo que son bugs reales. Mantenlo alto y la gente seguirá leyendo los resultados, que es la diferencia entre tener cobertura y tener un trabajo que se ejecuta cada noche.

¿Cuántas pruebas de UI deberíamos tener?

Menos de las que crees, elegidas según cuánto tiempo pasaría un fallo sin que nadie lo notara. Una suite pequeña en la que la gente confía gana a una grande que la gente ignora.

¿Qué tasa de aprobación es razonable aceptar?

Cualquier valor que no sea muy alto hace que la gente deje de leer los resultados. Perseguir ese último pequeño porcentaje de inestabilidad vale más que añadir pruebas nuevas.

¿Las pruebas de UI deberían ejecutarse en cada commit?

En cada pull request suele ser la respuesta correcta. En cada commit suele ser demasiado lento para resultar útil y acaba desactivándose.

¿Y la regresión visual?

Es un asunto aparte, con su propio problema de tolerancia. Útil para sistemas de diseño, ruidosa para las pantallas de la aplicación.

¿Seguimos necesitando pruebas manuales?

Para el trabajo exploratorio y para todo lo que exija juzgar si algo se siente bien, sí. Para repetir las mismas comprobaciones, no.

La versión corta

Cubre lo que fallaría en silencio.

Las pruebas automatizadas de UI deberían elegirse según cuánto tiempo pasaría un fallo sin que nadie lo notara, y no según su importancia. Ancla en atributos estables, espera por estado, verifica lo que confirmaría una recarga y protege la proporción entre fallos reales y ruido de mantenimiento.