El Problema de la Explosión Combinatorial
Los sistemas de software modernos aceptan numerosos parámetros de entrada, cada uno con múltiples valores posibles. Probar todas las combinaciones rápidamente se vuelve inviable. Considera un formulario web simple con:
- País (195 opciones)
- Método de pago (5 opciones)
- Velocidad de envío (3 opciones)
- Envoltura de regalo (2 opciones: sí/no)
El testing exhaustivo requiere 195 × 5 × 3 × 2 = 5,850 casos de prueba. Agrega un parámetro más con 10 valores, y estás en 58,500 pruebas. Este es el problema de explosión combinatorial: el número de combinaciones posibles crece exponencialmente con los parámetros.
Sin embargo, la investigación muestra que la mayoría de las fallas de software son desencadenadas por interacciones entre un pequeño número de parámetros—típicamente 2 a 6. El estudio NIST encontró que 70-90% de los defectos son causados por fallas de parámetro único o interacciones 2-way, con rendimientos decrecientes más allá de cobertura 6-way.
El Diseño Combinatorial de Pruebas (CTD) aborda esto cubriendo sistemáticamente interacciones de parámetros sin testing exhaustivo.
¿Qué es el Testing Combinatorial?
El testing combinatorial asegura que todas las combinaciones t-way de valores de parámetros estén cubiertas por al menos un caso de prueba, donde t es la fuerza de interacción (típicamente 2-6). Este enfoque reduce dramáticamente el tamaño de la suite de pruebas mientras mantiene alta capacidad de detección de defectos.
Testing Pairwise (Cobertura 2-Way)
La forma más común es testing pairwise (cobertura 2-way): cada posible par de valores de parámetros aparece en al menos un caso de prueba.
Ejemplo: Formulario de Login
Parámetros:
- Username: [válido, inválido, vacío]
- Password: [válido, inválido, vacío]
- Recordarme: [marcado, desmarcado]
Testing exhaustivo: 3 × 3 × 2 = 18 pruebas
Cobertura pairwise logra la misma cobertura de interacción con solo 6 pruebas:
Test | Username | Password | Recordar |
---|---|---|---|
1 | válido | válido | marcado |
2 | válido | inválido | desmarcado |
3 | inválido | válido | desmarcado |
4 | inválido | inválido | marcado |
5 | vacío | válido | marcado |
6 | vacío | inválido | desmarcado |
Cada par de valores se prueba al menos una vez:
- (username válido, password válido) ✓
- (username válido, marcado) ✓
- (password inválido, desmarcado) ✓
- etc.
La investigación muestra que el testing pairwise detecta 50-90% de defectos mientras reduce el tamaño de la suite de pruebas en 80-95%.
Cobertura N-Way: Más Allá de Pairwise
La cobertura de mayor fuerza proporciona testing más exhaustivo al costo de suites de pruebas más grandes:
Niveles de Cobertura:
Fuerza | Nombre | Cobertura | Tamaño Típico | Detección de Defectos |
---|---|---|---|---|
1-way | Each Choice | Todos los valores individuales | Más pequeño | 50-60% |
2-way | Pairwise | Todos los pares de valores | Pequeño | 70-90% |
3-way | 3-way | Todos los triples de valores | Mediano | 90-95% |
4-way | 4-way | Todos los cuádruples de valores | Grande | 95-98% |
5-way | 5-way | Todos los quíntuples de valores | Muy grande | 98-99% |
6-way | 6-way | Todos los sextupletes de valores | Enorme | 99%+ |
Regla general: Comienza con cobertura 2-way. Aumenta a 3-way para sistemas críticos de seguridad o lógica de negocio compleja. Más allá de 4-way rara vez se justifica excepto para sistemas de misión crítica.
Ejemplo: Matriz de Compatibilidad de Navegadores
Parámetros:
- Navegador: [Chrome, Firefox, Safari, Edge]
- OS: [Windows, macOS, Linux]
- Resolución: [1920×1080, 1366×768, 2560×1440]
Exhaustivo: 4 × 3 × 3 = 36 pruebas Pairwise (2-way): 12 pruebas Cobertura 3-way: 18 pruebas
Ejemplo de array pairwise:
Test | Navegador | OS | Resolución |
---|---|---|---|
1 | Chrome | Windows | 1920×1080 |
2 | Chrome | macOS | 1366×768 |
3 | Chrome | Linux | 2560×1440 |
4 | Firefox | Windows | 1366×768 |
5 | Firefox | macOS | 2560×1440 |
6 | Firefox | Linux | 1920×1080 |
7 | Safari | Windows | 2560×1440 |
8 | Safari | macOS | 1920×1080 |
9 | Safari | Linux | 1366×768 |
10 | Edge | Windows | 2560×1440 |
11 | Edge | macOS | 1920×1080 |
12 | Edge | Linux | 1366×768 |
Este array cubre todas las interacciones pairwise:
- (Chrome, Windows), (Chrome, macOS), (Chrome, 1920×1080), etc.
- Cada navegador probado en cada OS
- Cada navegador probado en cada resolución
- Cada OS probado en cada resolución
ACTS: Sistema Avanzado de Testing Combinatorial
ACTS es una herramienta gratuita de NIST para generar covering arrays. Soporta varias fuerzas de cobertura y restricciones.
Instalación y Uso Básico
Descargar de: https://csrc.nist.gov/projects/automated-combinatorial-testing-for-software
Ejemplo: Configuración de Checkout E-commerce
Crear checkout.txt
:
[System]
Name: Checkout System
[Parameter]
Country (String) : US, UK, Canada, Germany, France
PaymentMethod (String) : CreditCard, PayPal, ApplePay, BankTransfer
ShippingSpeed (String) : Standard, Express, Overnight
GiftWrap (boolean) : true, false
[Constraint]
# Transferencia bancaria no disponible para envío nocturno
IF [ShippingSpeed] = "Overnight" THEN [PaymentMethod] <> "BankTransfer";
# Apple Pay solo en US y UK
IF [PaymentMethod] = "ApplePay" THEN ([Country] = "US" OR [Country] = "UK");
Generar covering array 2-way:
java -jar acts.jar checkout.txt 2
Salida: 15 casos de prueba cubriendo todas las interacciones pairwise (vs. 240 exhaustivo)
Restricciones en ACTS
Las restricciones eliminan combinaciones inválidas:
Ejemplo: Configuración de Software
[Parameter]
OS: Windows, Linux, macOS
Database: MySQL, PostgreSQL, Oracle
Edition: Community, Enterprise
[Constraint]
# Oracle solo disponible en edición Enterprise
IF [Database] = "Oracle" THEN [Edition] = "Enterprise";
# MySQL en macOS no soportado
IF [OS] = "macOS" THEN [Database] <> "MySQL";
ACTS genera arrays que respetan estas restricciones, evitando configuraciones imposibles.
Cobertura de Fuerza Mixta
ACTS soporta cobertura de fuerza variable: cobertura más fuerte para interacciones de parámetros críticos, más débil para otros.
[System]
Name: Medical Device Configuration
[Parameter]
DosageLevel: Low, Medium, High
PatientAge: Child, Adult, Senior
DeviceMode: Automatic, Manual
DisplayLanguage: English, Spanish, French, German
[Relation]
# Cobertura 3-way para parámetros médicos críticos
DosageLevel, PatientAge, DeviceMode (3)
# Cobertura 2-way para parámetro UI
DisplayLanguage (2)
Esto genera pruebas con cobertura 3-way para los parámetros médicos y 2-way para el parámetro UI—testing más fuerte donde más importa.
Covering Arrays: Fundamento Matemático
Un covering array CA(N; t, k, v) es un array N × k donde:
- N: número de casos de prueba
- t: fuerza de interacción
- k: número de parámetros
- v: número de valores por parámetro (asumiendo uniforme)
Propiedad: Cada sub-array N × t contiene todas las t-tuplas de v valores al menos una vez.
Ejemplo: CA(9; 2, 4, 3)
Un covering array para 4 parámetros, cada uno con 3 valores, con cobertura 2-way, usando 9 pruebas:
Test | P1 | P2 | P3 | P4 |
---|---|---|---|---|
1 | 0 | 0 | 0 | 0 |
2 | 0 | 1 | 1 | 2 |
3 | 0 | 2 | 2 | 1 |
4 | 1 | 0 | 1 | 1 |
5 | 1 | 1 | 2 | 0 |
6 | 1 | 2 | 0 | 2 |
7 | 2 | 0 | 2 | 2 |
8 | 2 | 1 | 0 | 1 |
9 | 2 | 2 | 1 | 0 |
Cada par (0,0), (0,1), (0,2), (1,0), (1,1), (1,2), (2,0), (2,1), (2,2) aparece en cada combinación de 2 columnas.
Método del Árbol de Clasificación (CTM)
El Método del Árbol de Clasificación proporciona un enfoque visual y jerárquico al testing combinatorial, particularmente útil para dependencias complejas.
Proceso CTM
- Identificar Clasificaciones: Categorías de alto nivel de condiciones de prueba
- Definir Clases: Valores o rangos específicos dentro de cada clasificación
- Construir Árbol de Clasificación: Estructura jerárquica mostrando relaciones
- Generar Combinaciones: Usar técnicas combinatoriales para seleccionar casos de prueba
Ejemplo: Sistema de Retiro de ATM
Árbol de Clasificación:
Retiro ATM
├── Estado de Cuenta
│ ├── Cuenta Válida
│ ├── Cuenta Congelada
│ └── Cuenta Cerrada
├── Condición de Balance
│ ├── Balance Suficiente
│ ├── Balance Insuficiente
│ └── Sobregiro Disponible
├── Monto de Retiro
│ ├── Dentro de Límite Diario
│ ├── Excede Límite Diario
│ └── Balance Exacto
└── Estado de Tarjeta
├── Tarjeta Válida
├── Tarjeta Expirada
└── Reportada Robada
Combinaciones Pairwise generadas de este árbol aseguran cobertura comprehensiva de escenarios realistas mientras eliminan combinaciones sin sentido (ej., cuenta cerrada con retiro).
PICT: Herramienta Práctica de Testing Combinatorial
PICT (Pairwise Independent Combinatorial Testing) es la herramienta gratuita de línea de comandos de Microsoft para generar casos de prueba combinatoriales.
Instalación
Descargar de: https://github.com/Microsoft/pict
# macOS/Linux
wget https://github.com/Microsoft/pict/releases/download/v3.7.4/pict
chmod +x pict
# Windows
# Descargar pict.exe de la página de releases
Uso Básico
Crear model.txt
:
Browser: Chrome, Firefox, Safari, Edge
OS: Windows, macOS, Linux
Resolution: 1920x1080, 1366x768, 2560x1440
ColorDepth: 16bit, 32bit
Generar pruebas pairwise:
./pict model.txt
Salida (12 pruebas):
Browser OS Resolution ColorDepth
Chrome Windows 1920x1080 16bit
Chrome macOS 1366x768 32bit
Chrome Linux 2560x1440 32bit
Firefox Windows 1366x768 32bit
Firefox macOS 2560x1440 16bit
Firefox Linux 1920x1080 32bit
Safari Windows 2560x1440 32bit
Safari macOS 1920x1080 16bit
Safari Linux 1366x768 16bit
Edge Windows 2560x1440 16bit
Edge macOS 1920x1080 32bit
Edge Linux 1366x768 32bit
Características Avanzadas de PICT
Restricciones:
Browser: Chrome, Firefox, Safari, Edge
OS: Windows, macOS, Linux
ClearTypeSupport: Yes, No
IF [Browser] = "Safari" THEN [OS] <> "Windows";
IF [OS] = "macOS" THEN [ClearTypeSupport] = "No";
Cobertura de orden superior:
# Cobertura 3-way
./pict model.txt /o:3
# Semilla aleatoria para reproducibilidad
./pict model.txt /r:42
# Parámetros sensibles a mayúsculas
./pict model.txt /c
Caso de Estudio: Testing de Configuración de Servicio en la Nube
Una plataforma en la nube ofrece servicios configurables en múltiples dimensiones:
Parámetros:
- Región: [US-East, US-West, EU-Central, Asia-Pacific] (4)
- Tipo de Instancia: [Micro, Small, Medium, Large, XLarge] (5)
- Tipo de Almacenamiento: [SSD, HDD, NVMe] (3)
- Frecuencia de Backup: [None, Daily, Hourly] (3)
- Auto-scaling: [Enabled, Disabled] (2)
- Load Balancer: [None, Basic, Advanced] (3)
Exhaustivo: 4 × 5 × 3 × 3 × 2 × 3 = 1,080 pruebas
Desafíos:
- Probar todas las combinaciones es inviable
- Algunas combinaciones inválidas (ej., instancia Micro con load balancer Advanced)
- Interacciones críticas necesitan cobertura más fuerte
Solución: CTD de Fuerza Mixta
[Parameter]
Region: US-East, US-West, EU-Central, Asia-Pacific
InstanceType: Micro, Small, Medium, Large, XLarge
StorageType: SSD, HDD, NVMe
BackupFrequency: None, Daily, Hourly
AutoScaling: Enabled, Disabled
LoadBalancer: None, Basic, Advanced
[Constraint]
# Instancias Micro no soportan load balancing avanzado
IF [InstanceType] = "Micro" THEN [LoadBalancer] <> "Advanced";
# Auto-scaling requiere load balancer
IF [AutoScaling] = "Enabled" THEN [LoadBalancer] <> "None";
# NVMe solo disponible para Large y XLarge
IF [StorageType] = "NVMe" THEN ([InstanceType] = "Large" OR [InstanceType] = "XLarge");
[Relation]
# Cobertura 3-way para combinaciones críticas de rendimiento
InstanceType, StorageType, LoadBalancer (3)
# Cobertura 2-way para otros parámetros
Region, BackupFrequency, AutoScaling (2)
Resultado: 47 pruebas con cobertura 3-way para parámetros críticos, 2-way para otros—Reducción del 95.6% del testing exhaustivo.
Resultado:
- Descubrió 12 bugs de configuración en el primer ciclo de pruebas
- Encontró caso límite: backup horario + auto-scaling causó agotamiento de cuota de almacenamiento
- Identificó 3 problemas de rendimiento específicos de región
- Tiempo de ejecución de pruebas reducido de 90 horas estimadas a 4 horas
Mejores Prácticas para Testing Combinatorial
1. Comienza con Modelado de Parámetros
Identifica cuidadosamente parámetros y valores:
- Demasiado granular: Explosión de casos de prueba
- Demasiado grueso: Defectos omitidos
Ejemplo: En lugar de “Edad: 1, 2, 3, …, 120”, usa clases de equivalencia: “Edad: Niño (0-12), Adolescente (13-17), Adulto (18-64), Senior (65+)”
2. Usa Restricciones Sabiamente
Documenta combinaciones inválidas:
- Incompatibilidades de hardware
- Reglas de negocio
- Limitaciones técnicas
Las restricciones reducen el tamaño de la suite de pruebas y previenen esfuerzo desperdiciado en escenarios imposibles.
3. Prioriza Interacciones Críticas
Usa cobertura de fuerza mixta:
- 3-4 way para parámetros críticos de seguridad
- 2-way para funcionalidad estándar
- 1-way (each choice) para parámetros de bajo riesgo
4. Combina con Otras Técnicas
CTD complementa pero no reemplaza:
- Análisis de valores límite: Prueba límites de parámetros
- Error guessing: Agrega pruebas para áreas problemáticas conocidas
- Testing basado en riesgos: Suplementa brechas de cobertura para escenarios de alto riesgo
5. Itera y Refina
Primera iteración: Genera covering array Revisión: Examina pruebas para realismo Refinación: Agrega restricciones, ajusta valores de parámetros Re-genera: Produce suite de pruebas mejorada
6. Automatiza Generación y Ejecución
Integra CTD en CI/CD:
# Generar pruebas
pict config.txt > test_cases.csv
# Convertir a pruebas ejecutables
python generate_tests.py test_cases.csv > test_suite.py
# Ejecutar
pytest test_suite.py
Comparación de Herramientas
Herramienta | Fuerza | Plataforma | Restricciones | GUI | Licencia |
---|---|---|---|---|---|
ACTS | 2-6 way, mixta | Java | Sí (compleja) | Sí | Gratis |
PICT | 2-6 way | CLI | Sí (básica) | No | Gratis |
TestCover.com | 2-6 way | Web | Sí | Sí | Freemium |
CTE XL | Basado en CTM | Windows | Sí | Sí | Comercial |
AllPairs | 2-way | Script Python | No | No | Gratis |
CoverTable | 2-way | Excel | Básica | Excel | Gratis |
Recomendación:
- Pairwise rápido: PICT (rápido, sintaxis simple)
- Restricciones complejas: ACTS (lenguaje de restricciones poderoso)
- Modelado visual: CTE XL o TestCover.com
- Integración CI/CD: PICT (scriptable, ligero)
Conclusión: Eficiencia A Través de Matemáticas
El Diseño Combinatorial de Pruebas aplica rigor matemático al problema práctico de explosión de pruebas. Al cubrir sistemáticamente interacciones de parámetros en lugar de probar exhaustivamente todas las combinaciones, CTD logra:
- Reducción dramática de suite de pruebas: 80-95% menos pruebas
- Alta detección de defectos: 70-95% de bugs encontrados (con cobertura 2-way)
- Cobertura basada en principios: Garantía matemática de cobertura de interacción
- Manejo de restricciones: Eliminación de combinaciones inválidas
La técnica es particularmente valiosa para:
- Testing de configuración (navegadores, OS, hardware)
- Combinaciones de parámetros API
- Testing de feature flags
- Matrices de compatibilidad
- Reglas de negocio complejas con múltiples condiciones
Comienza con testing pairwise usando PICT o ACTS, agrega restricciones para eliminar casos inválidos y aumenta la fuerza de cobertura para interacciones críticas. La inversión en aprender testing combinatorial paga dividendos en tiempo de testing reducido y detección de defectos mejorada.
Cuando enfrentes combinaciones exponenciales, recuerda: no necesitas probar todo—necesitas probar las interacciones que importan. El testing combinatorial proporciona el framework matemático para hacer exactamente eso.