¿Qué es el testing basado en modelos?
El testing basado en modelos (MBT) es un enfoque donde creas un modelo formal del comportamiento esperado del sistema, y luego usas herramientas para generar automáticamente test cases a partir de ese modelo. En lugar de escribir manualmente cientos de tests, construyes un modelo y dejas que los algoritmos deriven los tests.
El flujo de trabajo MBT:
- Analizar requisitos — entender el comportamiento del sistema
- Construir un modelo — representar el comportamiento como modelo formal
- Generar tests — usar herramientas MBT para derivar test cases
- Ejecutar tests — correr los tests generados contra el sistema
- Evaluar resultados — el modelo sirve como oráculo
- Mantener el modelo — actualizar cuando cambien los requisitos
¿Por qué MBT?
Problemas del diseño manual:
- Diseñadores interpretan requisitos diferentemente
- Se pierden caminos importantes
- Mantener miles de test cases manuales es costoso
- Criterios de cobertura son difíciles de satisfacer manualmente
Ventajas de MBT:
- Cobertura sistemática garantizada
- Regeneración automática al cambiar el modelo
- Construcción del modelo revela ambigüedades en requisitos
- Escalabilidad — modelos describen comportamiento concisamente
Tipos de modelos para MBT
Máquinas de estado finitas (FSM)
Ejemplo: Sesión de ATM
Estados: Idle, CardInserted, PINEntry, Authenticated, Transaction, Dispensing, Error
Transiciones:
Idle → CardInserted [insertCard]
CardInserted → PINEntry [cardValid]
PINEntry → Authenticated [correctPIN]
PINEntry → PINEntry [wrongPIN, attempts < 3]
PINEntry → Error [wrongPIN, attempts >= 3]
Authenticated → Transaction [selectWithdraw]
Transaction → Dispensing [sufficientFunds]
Dispensing → Idle [cashTaken]
Error → Idle [ejectCard]
Máquinas de estado extendidas (EFSM)
FSMs con variables, guardas y acciones.
Diagramas de actividad UML
Para workflows y procesos de negocio.
Cadenas de Markov
Modelos probabilísticos para testing estadístico.
Criterios de cobertura
| Criterio | Descripción | Rigor |
|---|---|---|
| Cobertura de estados | Visitar cada estado | Débil |
| Cobertura de transiciones | Tomar cada transición | Moderado |
| Cobertura switch | Cada par de transiciones consecutivas | Fuerte |
| All-paths | Cada camino distinto | Más fuerte |
Herramientas MBT
Open Source
- GraphWalker — Java, FSM y EFSM, API REST
- ModelJUnit — Extensión JUnit para FSM
- NModel — Framework .NET
- Spec Explorer — Microsoft, testing de protocolos
Comerciales
- Conformiq — Enterprise MBT
- Smartesting — Generación con UML
- MaTeLo — MBT con cadenas de Markov
Cuándo MBT funciona mejor
Buenos candidatos:
- Implementaciones de protocolos (APIs, protocolos de red)
- Sistemas embedded con comportamiento de estado definido
- Workflows de procesos de negocio
- Sistemas con muchos caminos válidos
- Productos de larga vida
Malos candidatos:
- Aplicaciones CRUD simples
- Aplicaciones heavy en UI
- Sistemas donde los requisitos cambian más rápido que los modelos
- Proyectos únicos
Ejercicio: Construyendo un modelo MBT
Problema 1
Construye un modelo de máquina de estados para un carrito de compras:
- Cart empieza Empty
- Se pueden agregar items (Empty → HasItems, HasItems → HasItems)
- Se pueden remover items (HasItems → HasItems o HasItems → Empty)
- Proceder a Checkout (HasItems → Checkout)
- Aplicar cupón (Checkout → Checkout)
- Enviar orden (Checkout → OrderPlaced)
- Orden falla (Checkout → PaymentFailed)
- Reintentar (PaymentFailed → Checkout)
- Volver al carrito (Checkout → HasItems)
Solución
Estados: Empty, HasItems, Checkout, PaymentFailed, OrderPlaced
Transiciones:
- Empty → HasItems [addItem]
- HasItems → HasItems [addItem]
- HasItems → HasItems [removeItem, items > 1]
- HasItems → Empty [removeItem, items == 1]
- HasItems → Checkout [proceedToCheckout]
- Checkout → Checkout [applyCoupon]
- Checkout → OrderPlaced [submitOrder, success]
- Checkout → PaymentFailed [submitOrder, fail]
- PaymentFailed → Checkout [retryPayment]
- Checkout → HasItems [backToCart]
Tests para cobertura de transiciones:
Test 1 (cubre 1, 2, 5, 6, 7): addItem → addItem → proceedToCheckout → applyCoupon → submitOrder(success)
Test 2 (cubre 3, 4): addItem → addItem → removeItem → removeItem
Test 3 (cubre 8, 9, 10): addItem → proceedToCheckout → submitOrder(fail) → retryPayment → backToCart
3 tests cubren las 10 transiciones.
Problema 2
Evalúa si MBT es apropiado para estos proyectos:
- API bancaria con 50 endpoints y gestión de estado compleja
- Landing page de marketing con formulario de contacto
- Firmware IoT que gestiona sensores, alertas y protocolos
Solución
- API bancaria — Sí. Estado complejo, protocolo definido, muchos caminos, requisitos regulatorios.
- Landing page — No. Comportamiento simple, el esfuerzo de modelado excede el beneficio.
- Firmware IoT — Sí. Estados definidos, comportamiento predecible, testing de conformidad de protocolo.
Desafíos y limitaciones
- Mantenimiento del modelo: Debe sincronizarse con el sistema
- Complejidad del modelo: Si es tan complejo como el sistema, se pierde el beneficio
- Curva de aprendizaje: Equipos necesitan capacitación
- Problema del oráculo: ¿Qué pasa si el modelo está mal?
- Propiedades no funcionales: MBT no aborda performance ni seguridad directamente
Puntos clave
- MBT genera tests automáticamente desde modelos comportamentales
- Las FSM son el tipo de modelo más común
- Las herramientas garantizan criterios de cobertura (estados, transiciones, switch)
- Construir el modelo revela ambigüedades en requisitos
- Mejores candidatos: protocolos, sistemas embedded, workflows complejos
- El modelo sirve como generador de tests y como oráculo
- El mantenimiento del modelo es el mayor costo continuo