Probar un campo de edad que acepta entre 18 y 65 años con valores aleatorios como 25, 42 y 60 no te dice nada que el primer valor no haya dicho ya. Los bugs se esconden en los bordes: 17, 18, 65 y 66, exactamente donde aparece un error de desplazamiento en la condición. Este artículo cubre las cinco técnicas sistemáticas para decidir qué entradas probar: particionamiento de equivalencia, análisis de valores límite, tablas de decisión, testing de transición de estados y testing combinatorio por pares, con una guía para elegir entre ellas según el tipo de funcionalidad.

Particionamiento de equivalencia: dejá de probar lo mismo dos veces

La idea central es simple: si dos entradas van a producir el mismo comportamiento, solo necesitas probar una. Divides el espacio total de entradas en grupos (llamados particiones o clases de equivalencia) donde cada valor del grupo se comporta de la misma manera. Luego pruebas un valor representativo de cada grupo.

Considera un formulario de registro con un campo de edad. El requisito dice que los usuarios deben tener entre 18 y 65 años. Podrías probar cada entero de 0 a 120, pero eso son 121 casos de prueba. El particionamiento de equivalencia te dice que solo hay cuatro grupos que importan:

| Partición | Rango | Valor ejemplo |

|-----------|-------|---------------|

| Válida | 18-65 | 35 |

| Demasiado joven (inválida) | Menor de 18 | 10 |

| Demasiado mayor (inválida) | Mayor de 65 | 80 |

| Tipo incorrecto (inválida) | No numérico | "veinte" |

Cuatro casos de prueba en lugar de 121. La lógica es que si 35 pasa y 36 también pasa, probar 36 no te da información adicional. Si 10 falla correctamente, 11 también fallará.

El particionamiento de equivalencia se aplica a cualquier entrada con un rango válido definido: campos de texto con límites de longitud, listas desplegables con valores permitidos, carga de archivos con restricciones de tamaño, parámetros de API con valores válidos enumerados.

Análisis de valores límite: donde se esconden los bugs

Los desarrolladores cometen errores en los bordes. Un error de desplazamiento se ve así: if (age > 18) en lugar de if (age >= 18). El particionamiento de equivalencia encuentra las particiones; el análisis de valores límite (BVA) prueba las paredes entre ellas.

Para el mismo campo de edad 18-65, BVA produce estos casos de prueba:

| Valor | Límite de partición | Resultado esperado |

|-------|---------------------|--------------------|

| 17 | Justo debajo del límite inferior | Rechazado |

| 18 | Límite inferior | Aceptado |

| 19 | Justo encima del límite inferior | Aceptado |

| 64 | Justo debajo del límite superior | Aceptado |

| 65 | Límite superior | Aceptado |

| 66 | Justo encima del límite superior | Rechazado |

Seis casos de prueba que cubren ambos límites por ambos lados. Combinado con el particionamiento de equivalencia (que maneja el medio y el caso de tipo incorrecto), tienes una suite de pruebas completa para este campo con unos 8-10 casos en total.

BVA funciona en cualquier lugar donde haya un límite: longitudes máximas de caracteres en campos de texto, cantidades mínimas de pedido en e-commerce, límites de tamaño de archivo, rangos de fechas, conteos de páginas de paginación, límites de rate de API. El patrón es siempre el mismo: prueba el valor en el límite, uno por debajo y uno por encima.

Cuando encuentras un bug con BVA, casi siempre está exactamente en el límite. Un campo de edad que rechaza 65 pero acepta 64 y 66 revela un error de desplazamiento. Nómbralo específicamente en tu reporte de bug. "Fallo de condición de límite en el extremo superior" ayuda al desarrollador a encontrarlo más rápido.

Tablas de decisión: hacer visible la lógica de negocio

Algunas funcionalidades no tienen una entrada única con un rango; tienen múltiples condiciones que se combinan para producir resultados diferentes. Descuentos en checkout, reglas de acceso a contenido, actualizaciones de suscripción, preferencias de notificación: todas estas tienen lógica combinatoria compleja que es difícil de razonar solo a partir de los requisitos.

Las tablas de decisión hacen esa lógica explícita. Cada columna es un caso de prueba. Cada fila es una condición o un resultado.

Toma una funcionalidad de descuentos: los usuarios obtienen descuento si tienen tarjeta de fidelidad o si su total de compra supera los $100. Las combinaciones se ven así:

| | Caso 1 | Caso 2 | Caso 3 | Caso 4 |

|---|---|---|---|---|

| Tiene tarjeta de fidelidad | No | Sí | No | Sí |

| Compra > $100 | No | No | Sí | Sí |

| Obtiene descuento | No | Sí | Sí | Sí |

Es una regla OR, así que tres de los cuatro casos resultan en descuento. Cuatro casos de prueba, uno por columna. Si la regla fuera AND (debe tener tarjeta de fidelidad Y compra mayor de $100), solo el Caso 4 calificaría. La tabla lo mostraría de inmediato, y sabrías que tienes que probar las cuatro combinaciones para confirmar la lógica.

Las tablas de decisión brillan cuando los requisitos contienen palabras como "si", "cuando", "a menos que", "excepto cuando", "pero solo si". Esas palabras señalan que la lógica condicional necesita mapearse. La tabla te obliga a enumerar cada combinación, lo que frecuentemente revela casos que los requisitos no especificaron. ¿Qué pasa si el usuario no tiene tarjeta de fidelidad y su pedido es exactamente $100? La tabla hace visible esa ambigüedad antes del desarrollo, cuando es barato resolverla.

Para una funcionalidad con tres condiciones binarias, obtienes 2³ = 8 combinaciones. Para cuatro condiciones, 16. Las tablas de decisión no siempre requieren probar todas las combinaciones (algunas pueden ser imposibles o irrelevantes), pero te ayudan a ver el espacio completo antes de decidir cuáles descartar.

Testing de transición de estados: funcionalidades que recuerdan dónde estuvieron

Algunas funcionalidades no solo responden a entradas; mantienen estado, y las acciones válidas dependen de en qué estado están actualmente. Flujos de autenticación, flujos de trabajo de estados de pedido, gestión de suscripciones, ciclo de vida de cuentas de usuario: todos se comportan distinto dependiendo de lo que ya ocurrió.

El testing de transición de estados mapea los estados en que puede estar una funcionalidad, los eventos que causan transiciones entre estados, y los resultados o comportamientos esperados durante cada transición.

Toma la gestión de cuentas de usuario. Una cuenta puede estar en uno de tres estados: Activa, Bloqueada y Suspendida. Las transiciones entre ellas las disparan eventos específicos:

| Estado actual | Evento | Siguiente estado | Comportamiento esperado |

|---------------|--------|-----------------|------------------------|

| Activa | 5 logins fallidos | Bloqueada | Mostrar mensaje de bloqueo, bloquear intentos futuros |

| Activa | Admin suspende | Suspendida | Mostrar aviso de suspensión, cerrar sesiones activas |

| Bloqueada | Pasan 15 minutos | Activa | Permitir intentos de login nuevamente |

| Bloqueada | Admin desbloquea | Activa | Acceso restaurado de inmediato |

| Suspendida | Admin reinstala | Activa | Cuenta restaurada, usuario notificado |

| Suspendida | 5 logins fallidos | Suspendida | Continúa suspendida (sin transición) |

De esta tabla derivas dos tipos de casos de prueba. El primero verifica transiciones válidas: confirmar que "Activa + 5 logins fallidos → Bloqueada" funciona según lo documentado. El segundo verifica transiciones inválidas: confirmar que una cuenta Suspendida no puede transicionar a Bloqueada intentando hacer login, y que el sistema maneja ese caso correctamente.

La tabla también revela lagunas. ¿Qué pasa si una cuenta Bloqueada recibe el evento "Admin suspende"? El requisito puede no decirlo. Los diagramas de transición de estados hacen visibles esas lagunas como celdas vacías.

El testing de transición de estados es especialmente valioso para flujos de trabajo que los QA engineers junior tienden a sub-probar: ¿qué pasa si disparas una acción sobre un objeto que ya está en el estado "equivocado"? ¿Qué pasa si ejecutas el paso 3 antes que el paso 2? Las transiciones válidas son obvias; las inválidas son donde viven los bugs.

Testing combinatorio: cuando las combinaciones explotan

Algunas funcionalidades tienen tantas variables de entrada que una tabla de decisión completa no es viable. Un filtro de búsqueda con 5 opciones, cada una con 3-4 valores posibles, produce miles de combinaciones. No puedes probarlas todas.

El testing por pares (también llamado all-pairs testing) es la respuesta práctica. La investigación muestra que la mayoría de los bugs son causados por interacciones entre dos variables, no tres o más. El testing por pares garantiza que cada par de valores de variables diferentes aparece en al menos un caso de prueba.

Imagina probar un formulario de reserva de viajes con estas opciones:

  • Destino: Europa, Asia, América (3 valores)
  • Tipo de viaje: Solo ida, Ida y vuelta (2 valores)
  • Clase: Económica, Ejecutiva, Primera (3 valores)
  • Mes de salida: Verano, Invierno (2 valores)

Testing factorial completo: 3 × 2 × 3 × 2 = 36 combinaciones. El testing por pares cubre todos los pares en aproximadamente 9 casos de prueba.

No construyes los conjuntos de tests por pares a mano. Hay herramientas que lo hacen. PICT (Pairwise Independent Combinatorial Testing) es una herramienta gratuita de línea de comandos de Microsoft. AllPairs es otra. Defines tus parámetros y valores, ejecutas la herramienta y obtienes un conjunto mínimo de tests.

El testing por pares es la opción correcta cuando tienes 4 o más variables con múltiples valores cada una, cuando la cobertura factorial completa no es factible con el tiempo disponible, y cuando necesitas un método defendible para reducir el alcance de las pruebas sin simplemente adivinar qué combinaciones saltear.

Qué técnica usar: guía de decisión

Las técnicas no son mutuamente excluyentes. La mayoría de las funcionalidades reales usa más de una.

Particionamiento de equivalencia

Aplica a cualquier entrada con un rango válido definido: campos de edad, rangos de precios, límites de longitud de caracteres, valores válidos enumerados. Úsalo para organizar las entradas antes de escribir casos de prueba individuales.

Análisis de valores límite

Se combina con el particionamiento de equivalencia para las mismas situaciones. Cada vez que el particionamiento de equivalencia identifica un límite, añade casos de prueba BVA alrededor de ese límite. Siempre.

Tablas de decisión

Aplican a funcionalidades con múltiples condiciones independientes que se combinan para producir resultados diferentes. Si los requisitos usan lógica "si/y/o/a menos que", construye una tabla de decisión antes de escribir los casos de prueba.

Testing de transición de estados

Aplica a funcionalidades con un ciclo de vida o flujo de trabajo definido. Si un objeto (usuario, pedido, ticket, suscripción) puede estar en diferentes estados y transicionar entre ellos, mapea los estados primero, luego deriva los casos de prueba.

Testing por pares

Aplica al testing de configuración y funcionalidades con muchas variables independientes. Si tienes más de 3-4 variables y la cobertura completa no es viable, usa una herramienta por pares.

Para un campo de entrada simple sin estado y sin lógica de múltiples condiciones, el particionamiento de equivalencia más BVA es todo lo que necesitas. Para un flujo de checkout complejo con descuentos, niveles de usuario y múltiples métodos de pago, las tablas de decisión más el testing de transición de estados te darán una cobertura más completa que cualquier intuición.

Cómo aplicar esto el lunes por la mañana

No necesitas reformar todo tu proceso de testing de una vez. Elige una funcionalidad que estés probando esta semana y aplica una técnica.

Si estás probando un campo de entrada con restricciones mínimas y máximas: escribe las particiones de equivalencia en papel antes de abrir la aplicación. Identifica los límites. Escribe los casos de prueba BVA. Tendrás una prueba completa del campo en cinco minutos en lugar de tipear valores aleatorios durante veinte.

Si estás probando una regla de negocio con múltiples condiciones (lógica de descuentos, control de acceso, triggers de notificaciones): construye la tabla de decisión antes de escribir cualquier caso de prueba. Cada columna se convierte en un caso de prueba. Verifica si alguna combinación es ambigua en los requisitos y pregunta antes de probar.

Si estás probando un flujo de trabajo con cambios de estado (gestión de pedidos, ciclo de vida de usuario, enrutamiento de tickets de soporte): dibuja el diagrama de estados, aunque sea esquemático. Lista las transiciones válidas y los eventos que las disparan. Luego escribe dos casos de prueba por transición: uno que confirme que funciona, otro que intente una transición inválida desde un estado similar.

→ See also: Cómo Escribir un Caso de Prueba: Formato, Ejemplos y Errores Comunes | Testing Basado en Riesgos: Priorizar Qué Testear Cuando No Puedes Testar Todo | Partición de Equivalencia y Análisis de Valores Límite: Guía Práctica | Caso de Prueba vs Escenario de Prueba: Diferencia y Cuándo Usar Cada Uno