
Imagina un formulario de login con dos campos: email y contraseña. Solo dos campos. Parece sencillo de probar. Pero si consideras emails válidos, inválidos, con caracteres especiales, vacíos, con espacios al inicio y al final, con dominios inexistentes, con mayúsculas y sin ellas, combinados con contraseñas cortas, largas, con y sin caracteres especiales, vacías, con espacios y con inyecciones SQL, las combinaciones ya se cuentan por miles. Y eso sin tocar la base de datos, el estado de la sesión, la red o el navegador. Probar todo es una promesa que nadie puede cumplir.
El segundo principio del testing según ISTQB establece que el testing exhaustivo es imposible. No dice que sea difícil o caro. Dice que es imposible. Salvo en casos triviales, no se pueden probar todas las combinaciones de entradas, precondiciones, estados y caminos de ejecución de un sistema.
La razón es matemática. Un programa con apenas 10 variables booleanas ya tiene 1.024 combinaciones posibles. Si cada variable tiene 5 valores posibles en lugar de 2, el número sube a casi 10 millones. En un sistema real con formularios, bases de datos, APIs externas, estados de sesión y configuraciones de entorno, el espacio de combinaciones es astronómico. Puedes dedicar toda tu vida a escribir tests y no cubrir ni una fracción significativa.
Glenford Myers ya lo planteó en The Art of Software Testing (1979): incluso un programa sencillo tiene tantos caminos posibles que el testing completo requeriría más tiempo del que dispone cualquier proyecto. La respuesta no es rendirse, sino elegir con inteligencia qué probar.
Vamos a ponerle números a un caso real. Un formulario de alta de usuario con cinco campos:
Si para cada campo defines apenas 10 valores representativos (válidos, inválidos, límite), tienes 105 combinaciones, es decir, 100.000 casos de prueba. Si cada test tarda 5 segundos en ejecutarse, necesitas casi 6 días de ejecución continua para una sola ronda. Y esos 10 valores por campo son una simplificación enorme. Ahora multiplica eso por los diferentes estados previos del sistema, los distintos navegadores y las configuraciones del servidor. El número de escenarios posibles supera cualquier capacidad de ejecución razonable.
Entender que el testing exhaustivo es imposible cambia fundamentalmente cómo abordas tu estrategia de testing. Si no puedes probar todo, la pregunta deja de ser “cuántos tests tenemos” y pasa a ser “estamos probando lo que más importa”.
En mi experiencia, cuando alguien en una reunión dice “hay que probar todo”, lo que realmente quiere decir es “no quiero que se me escape nada”. Es comprensible, pero es un objetivo imposible disfrazado de exigencia de calidad. El resultado suele ser una de dos cosas: o el equipo intenta probar todo y acaba con una suite enorme, lenta y difícil de mantener que aun así deja huecos, o se paraliza ante la magnitud de la tarea y acaba probando poco y mal.
He visto proyectos con 5.000 tests que tardaban 45 minutos en ejecutarse y donde la mitad probaban variaciones mínimas del mismo escenario. Mientras tanto, flujos críticos como la recuperación de contraseña o la renovación de tokens no tenían ni un solo test. La cantidad sin criterio no es cobertura, es ruido.
Cada hora que dedicas a escribir un test es una hora que no dedicas a otro. Si gastas tres horas probando 50 combinaciones de un campo de texto que rara vez falla, esas tres horas no se invirtieron en probar el flujo de pago que maneja dinero real y tiene tres integraciones externas. La priorización no es opcional, es la esencia misma del testing.
Negar la imposibilidad del testing exhaustivo produce errores de estrategia que son difíciles de corregir una vez instalados.
Si no puedes probar todo, necesitas un sistema para decidir qué probar primero, con cuánta profundidad y con qué técnicas. Aquí van las estrategias que mejor resultado dan en equipos reales.
No todas las funcionalidades tienen el mismo riesgo. Un bug en el flujo de pago tiene un impacto muy distinto a un bug en la página de “Acerca de”. Antes de escribir un solo test, clasifica las funcionalidades por dos ejes: la probabilidad de fallo (complejidad del código, frecuencia de cambios, dependencias externas) y el impacto si falla (pérdida económica, pérdida de datos, impacto en reputación).
Las funcionalidades con alta probabilidad y alto impacto reciben la mayor inversión en testing. Las de baja probabilidad y bajo impacto pueden cubrirse con tests mínimos o incluso depender de la monitorización en producción.
En lugar de probar todos los valores posibles de un campo, divides el rango en clases donde todos los valores deberían comportarse igual. Para un campo de edad que acepta entre 18 y 65 años, no necesitas probar 18, 19, 20, 21... hasta 65. Basta con un valor dentro del rango (por ejemplo, 30), uno por debajo (17) y uno por encima (66). Si el código trata correctamente a uno de la clase, debería tratar correctamente a todos.
Esta técnica reduce drásticamente el número de tests necesarios sin sacrificar la capacidad de detección. En el ejemplo anterior, pasas de 48 valores posibles a 3 tests que cubren los mismos escenarios lógicos.
Los bugs se acumulan en las fronteras. En el mismo campo de edad, los valores 17, 18, 65 y 66 son los que más probabilidades tienen de revelar defectos, porque es donde las condiciones del código cambian de aceptar a rechazar. Un típico error off-by-one no lo detectas probando con 30, sino probando con el valor exacto del límite y sus vecinos inmediatos.
Combina valores límite con particiones de equivalencia y tendrás un conjunto de tests compacto que cubre los puntos más sensibles del rango.
Cuando tienes múltiples campos que interactúan entre sí, el pairwise testing (o all-pairs) reduce las combinaciones de forma espectacular. La idea se basa en una observación empírica: la mayoría de los defectos se producen por la interacción de como mucho dos factores, no por combinaciones de tres, cuatro o cinco variables simultáneas. En lugar de probar todas las combinaciones posibles, generas un conjunto mínimo que garantice que cada par de valores entre dos campos aparece al menos una vez. Para un formulario con 4 campos de 3 valores cada uno, el testing exhaustivo necesita 81 combinaciones, mientras que el pairwise lo reduce a unas 9 o 12. Puedes usar generadores online o librerías específicas para crear esas combinaciones.
Tus usuarios reales ya te están diciendo qué probar. Analiza los logs de producción, los informes de errores y las métricas de uso para identificar los flujos más transitados, las entradas más comunes y las condiciones que generan más errores.
Si el 80 % de tus usuarios usa Chrome en móvil, tiene sentido que esa combinación tenga más cobertura que Safari en Linux. Si el 90 % de los registros usa Gmail, tus tests de email deberían cubrir bien ese caso, aunque también incluyan otros dominios. Los datos reales te ayudan a invertir el esfuerzo de testing donde más impacto tiene.
Aceptar que no puedes probar todo no es una debilidad. Es el punto de partida de cualquier estrategia de testing madura. Los equipos que mejor protegen su software no son los que tienen más tests, sino los que eligen mejor qué probar.
La próxima vez que alguien te pregunte “habéis probado todo?”, ten una respuesta preparada: “hemos identificado las áreas de mayor riesgo, aplicado técnicas de selección para cubrir el máximo con el mínimo esfuerzo y tenemos monitorización para detectar lo que se escape”. Eso inspira más confianza que un “sí, todo” que es mentira.
Un ejercicio para empezar: elige tu formulario más complejo, cuenta las combinaciones posibles si probaras todo y después aplica particiones de equivalencia y pairwise para ver cuántos tests realmente necesitas. La diferencia entre ambos números te convencerá de que el testing inteligente no es un atajo, sino la única opción viable.
Los scripts E2E necesitan datos sensibles —tokens de API, credenciales, URLs privadas— sin que aparezcan en el código. En JMO Labs hemos añadido variables de script con modo privado: se inyectan automáticamente, se enmascaran en los logs y se acceden con una sintaxis limpia.

Los tests E2E se rompen con cada cambio de interfaz. En JMO Labs construimos un pipeline de 5 fases con IA que planifica, ejecuta, repara selectores, diagnostica fallos y verifica resultados de forma autónoma. La caché de selectores hace que cada ejecución sea más rápida que la anterior.

Playwright no es solo para tests E2E. En JMO Labs lo usamos como motor completo: 9 fases de comprobación, localizador de 9 estrategias con self-healing, grabación de vídeo, testing responsive con viewports reales y accesibilidad con axe-core.