Introducción a los Enfoques de Testing
El testing de software no es de talla única. Diferentes enfoques de testing proporcionan diferentes perspectivas sobre la calidad, capturan diferentes tipos de bugs y requieren diferentes conjuntos de habilidades. Entender cuándo y cómo usar black box, white box y grey box testing es fundamental para construir una estrategia de testing efectiva.
Estos tres enfoques difieren principalmente en una dimensión: cuánto conocimiento tiene el tester sobre el funcionamiento interno del sistema que se está probando. Este conocimiento moldea qué técnicas pueden usarse, qué tipos de defectos pueden encontrarse y quién está mejor posicionado para realizar el testing.
En esta guía completa, exploraremos los tres enfoques en profundidad, examinaremos técnicas específicas para cada uno, entenderemos cuándo aplicar qué método y aprenderemos cómo combinarlos para máxima efectividad de pruebas.
Black Box Testing: Probando desde Afuera
¿Qué es Black Box Testing?
Definición: Black box testing trata el software como una “caja negra”—el tester no tiene conocimiento de la implementación interna, estructura de código o diseño. El testing se basa completamente en requisitos, especificaciones y comportamiento esperado. Para una guía detallada sobre técnicas específicas de black box, consulta nuestro artículo sobre testing de caja negra.
Características clave:
- Enfoque en qué hace el sistema, no cómo lo hace
- Basado en requisitos y especificaciones
- Sin acceso al código fuente
- Prueba comportamiento externo e interfaces
- Independiente del stack tecnológico
La perspectiva del tester:
Entrada → [CAJA NEGRA] → Salida
(Desconocido)
El tester conoce:
✓ Qué entradas proporcionar
✓ Qué salidas esperar
✗ Cómo procesa el sistema las entradas
✗ Lógica interna o algoritmos
✗ Estructura de código o arquitectura
Cuándo Usar Black Box Testing
Escenarios ideales:
- User acceptance testing: Validar desde perspectiva del usuario
- System testing: Probar sistema completo integrado
- Regression testing: Asegurar que funcionalidad existente sigue funcionando
- Software de terceros: Cuando no tienes acceso al código fuente
- Contract testing: Verificar cumplimiento con especificaciones
- Testing temprano: Cuando código no está disponible aún (testing basado en especificaciones)
Quién lo realiza:
- Testers de QA
- Analistas de negocio
- Usuarios finales
- Equipos de testing independientes
- Cualquiera sin conocimiento de codificación
Técnicas de Black Box Testing
1. Particionamiento de Equivalencia
Concepto: Dividir datos de entrada en clases equivalentes donde todos los valores en una clase deberían comportarse similarmente. Probar un valor representativo de cada partición.
Por qué funciona: Si un valor de una partición funciona, teóricamente todos los valores deberían funcionar. Si uno falla, todos deberían fallar.
Ejemplo: Validación de edad (debe ser 18-65)
Particiones de entrada:
1. Debajo del mínimo (edad < 18): INVÁLIDO
Valor de prueba: 17
2. Rango válido (18 ≤ edad ≤ 65): VÁLIDO
Valor de prueba: 30
3. Encima del máximo (edad > 65): INVÁLIDO
Valor de prueba: 66
En lugar de probar todas las edades posibles (1-120),
probamos 3 valores representativos: 17, 30, 66
Ejemplo: Campo de código de descuento
Particiones:
1. String vacío: INVÁLIDO
Prueba: ""
2. Formato válido (8 caracteres alfanuméricos): VÁLIDO
Prueba: "SAVE2024"
3. Muy corto (< 8 caracteres): INVÁLIDO
Prueba: "ABC"
4. Muy largo (> 8 caracteres): INVÁLIDO
Prueba: "VERYLONGCODE"
5. Caracteres especiales: INVÁLIDO
Prueba: "SAVE@#$%"
6. Válido pero código expirado: INVÁLIDO
Prueba: "EXPIRED1"
7. Válido pero ya usado: INVÁLIDO
Prueba: "USED1234"
Mejores prácticas:
- Identificar todas las condiciones de entrada
- Dividir en particiones válidas e inválidas
- Asegurar que particiones no se superpongan
- Asegurar que particiones cubran todas las posibilidades
- Probar cada partición al menos una vez
- Documentar la razón de cada partición
2. Análisis de Valores Límite (BVA)
Concepto: Los errores a menudo ocurren en los límites entre particiones de equivalencia. Probar valores en límites, justo dentro de límites y justo fuera de límites.
Por qué funciona: Errores off-by-one, errores de operador de comparación (< vs ≤) y casos edge a menudo se manifiestan en límites.
Ejemplo: Validación de edad (18-65)
Valores de prueba:
- Justo debajo del mínimo: 17 (debería fallar)
- Límite mínimo: 18 (debería pasar)
- Justo encima del mínimo: 19 (debería pasar)
- Rango medio: 42 (debería pasar)
- Justo debajo del máximo: 64 (debería pasar)
- Límite máximo: 65 (debería pasar)
- Justo encima del máximo: 66 (debería fallar)
7 pruebas en lugar de probar todas las edades 1-120
Ejemplo: Subida de archivo (máx 5MB)
Valores de prueba:
- 0 bytes (límite)
- 1 byte (justo encima del mínimo)
- 2.5 MB (rango medio)
- 4,999,999 bytes (justo debajo del máximo)
- 5,000,000 bytes (exactamente el máximo)
- 5,000,001 bytes (justo encima del máximo)
Ejemplo BVA bidimensional: Dimensiones de rectángulo
Ancho: 1-100 píxeles
Alto: 1-100 píxeles
Combinaciones de prueba:
(1, 1) - ambos mínimos
(1, 100) - ancho mín, alto máx
(100, 1) - ancho máx, alto mín
(100, 100) - ambos máximos
(0, 50) - ancho inválido
(50, 0) - alto inválido
(101, 50) - ancho excede
(50, 101) - alto excede
Mejores prácticas:
- Probar mínimo, máximo y justo fuera de ambos
- Para rangos, probar ambos extremos
- Combinar con particionamiento de equivalencia
- Considerar límites multidimensionales
- Probar valores null, vacíos y en blanco
3. Testing de Tabla de Decisión
Concepto: Representar lógica de negocio compleja con combinaciones de condiciones y acciones correspondientes en formato de tabla.
Cuándo usar:
- Múltiples condiciones afectan resultados
- Reglas de negocio complejas
- Diferentes combinaciones producen diferentes resultados
- Necesidad de verificar todas las combinaciones
Ejemplo: Sistema de aprobación de préstamo
Condiciones:
C1: Puntaje de crédito >= 700
C2: Ingreso >= $50,000
C3: Relación deuda-ingreso < 40%
C4: Empleo > 2 años
Acciones:
A1: Aprobar préstamo
A2: Rechazar préstamo
A3: Requiere revisión manual
Tabla de decisión:
Regla | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
---------|---|---|---|---|---|---|---|---|
C1 | V | V | V | V | F | F | F | F |
C2 | V | V | F | F | V | V | F | F |
C3 | V | F | V | F | V | F | V | F |
C4 | V | F | V | F | V | F | V | F |
---------|---|---|---|---|---|---|---|---|
A1 | X | | | | | | | |
A2 | | | | X | | | | X |
A3 | | X | X | | X | X | X | |
Regla 1: Todas las condiciones cumplidas → Aprobar
Regla 2: Buen crédito pero alta deuda → Revisión manual
Regla 3: Buen crédito, baja deuda, pero bajo ingreso → Revisión manual
Regla 4: Solo puntaje de crédito bueno → Rechazar
...y así sucesivamente
Mejores prácticas:
- Identificar todas las condiciones y acciones
- Listar todas las combinaciones (o reducir con equivalencia)
- Asegurar completitud (todos los casos cubiertos)
- Buscar combinaciones redundantes o imposibles
- Priorizar escenarios comunes
4. Testing de Transición de Estado
Concepto: Probar cómo un sistema transiciona entre diferentes estados basándose en entradas y eventos.
Cuándo usar:
- Sistemas con estados distintos
- Comportamiento dependiente del estado
- Flujos de trabajo y procesos
- Sistemas de transacciones
Ejemplo: Ciclo de vida de pedido
Estados:
- Nuevo
- Pagado
- Enviado
- Entregado
- Cancelado
Transiciones:
Nuevo → Pagado (evento: pago recibido)
Nuevo → Cancelado (evento: cliente cancela)
Pagado → Enviado (evento: pedido despachado)
Pagado → Cancelado (evento: pago reembolsado)
Enviado → Entregado (evento: entrega confirmada)
Enviado → Cancelado (evento: perdido en tránsito)
Transiciones inválidas:
Nuevo → Enviado (no se puede enviar pedido no pagado)
Entregado → Pagado (no se puede pagar después de entrega)
Cancelado → Enviado (no se puede enviar pedido cancelado)
Casos de prueba:
1. Nuevo → Pagado → Enviado → Entregado (camino feliz)
2. Nuevo → Cancelado (cancelación temprana)
3. Pagado → Cancelado (escenario de reembolso)
4. Intentar Nuevo → Enviado (debería fallar)
5. Intentar Entregado → Cancelado (debería fallar o reembolso parcial)
Mejores prácticas:
- Crear diagrama de transición de estado
- Probar todas las transiciones válidas
- Probar transiciones inválidas (deberían ser rechazadas)
- Probar secuencias de transiciones
- Verificar que datos de estado persisten correctamente
5. Testing de Caso de Uso
Concepto: Probar escenarios basados en cómo los usuarios realmente usarán el sistema. Enfocarse en flujos de trabajo de usuario end-to-end.
Estructura de caso de uso:
Caso de Uso: Realizar un pedido
Actor: Cliente
Precondiciones:
- Usuario está autenticado
- Artículos están en stock
- Método de pago está configurado
Flujo Principal:
1. Usuario agrega artículos al carrito
2. Usuario revisa carrito
3. Usuario procede al checkout
4. Usuario confirma dirección de envío
5. Usuario selecciona método de pago
6. Usuario revisa pedido
7. Usuario realiza pedido
8. Sistema procesa pago
9. Sistema confirma pedido
10. Usuario recibe email de confirmación
Flujos Alternos:
- 2a. Usuario aplica código de descuento
- 6a. Usuario edita dirección de envío
- 8a. Pago falla → Usuario intenta método de pago diferente
Flujos de Excepción:
- 1a. Artículo fuera de stock → Usuario es notificado
- 8a. Gateway de pago caído → Usuario ve error, pedido guardado
Postcondiciones:
- Pedido creado en base de datos
- Inventario actualizado
- Email de confirmación enviado
- Pago registrado
Mejores prácticas:
- Basar en escenarios de usuario reales
- Incluir caminos felices y flujos alternos
- Probar escenarios de excepción
- Verificar precondiciones y postcondiciones
- Documentar comportamiento del sistema esperado
6. Adivinación de Errores
Concepto: Aprovechar experiencia del tester para adivinar dónde es probable que ocurran errores.
Áreas comunes propensas a errores:
Entrada de datos:
- Campos vacíos
- Caracteres especiales (!@#$%^&*)
- Entradas muy largas
- Intentos de inyección SQL
- Intentos XSS
Cálculos:
- División por cero
- Números negativos
- Números muy grandes
- Problemas de precisión decimal
Fechas y horas:
- 29 de febrero (año bisiesto)
- Diferencias de formato de fecha
- Cambios de zona horaria
- Horario de verano
- Problema del año 2038
Concurrencia:
- Dos usuarios editando mismo registro
- Clic rápido
- Múltiples pestañas/ventanas
- Race conditions
Límites de recursos:
- Subida de tamaño máximo de archivo
- Registros máximos
- Límites de conexión a base de datos
- Agotamiento de memoria
Mejores prácticas:
- Documentar áreas problemáticas conocidas
- Aprender de bugs pasados
- Compartir conocimiento entre equipo
- Combinar con técnicas formales
- Mantener base de datos de defectos para patrones
Black Box Testing: Ventajas y Desventajas
Ventajas:
✓ No se requiere conocimiento de programación
✓ Testing imparcial (no influenciado por código)
✓ Perspectiva centrada en el usuario
✓ Puede comenzar temprano (antes de que se escriba código)
✓ Separación clara de roles (dev vs test)
✓ Eficiente para sistemas grandes
✓ Se enfoca en cobertura de requisitos
Desventajas:
✗ No puede probar lógica interna directamente
✗ Puede perder funcionalidad oculta
✗ Difícil identificar causa de fallos
✗ No puede medir cobertura de código
✗ Potencialmente pruebas redundantes
✗ Puede no capturar problemas arquitectónicos
✗ Limitado a lo que definen las especificaciones
White Box Testing: Probando desde Adentro
¿Qué es White Box Testing?
Definición: White box testing (también llamado glass box, clear box o structural testing) examina la estructura interna, diseño y código del software. El tester tiene visibilidad completa de la implementación. Para profundizar en las técnicas de white box, consulta nuestro artículo sobre testing de caja blanca.
Características clave:
- Enfoque en cómo funciona el sistema internamente
- Basado en estructura de código y lógica
- Acceso completo al código fuente
- Prueba rutas internas, condiciones, bucles
- Requiere conocimiento de programación
La perspectiva del tester:
Entrada → [CAJA CLARA] → Salida
(Código Visible)
El tester conoce:
✓ Código fuente
✓ Algoritmos internos
✓ Estructura de código
✓ Schema de base de datos
✓ Arquitectura
✓ Dependencias
Cuándo Usar White Box Testing
Escenarios ideales:
- Unit testing: Probar funciones/métodos individuales
- Integration testing: Probar interacciones de módulos
- Optimización de código: Encontrar cuellos de botella de rendimiento
- Security testing: Identificar vulnerabilidades
- Code review: Asegurar estándares de calidad
- Algoritmos complejos: Verificar corrección de lógica
Quién lo realiza:
- Desarrolladores
- SDET (Software Development Engineers in Test)
- QA técnico con habilidades de codificación
- Especialistas de seguridad
- Ingenieros de rendimiento
Técnicas de White Box Testing
1. Cobertura de Sentencias
Objetivo: Ejecutar cada sentencia en el código al menos una vez.
Fórmula: Cobertura de Sentencias = (Sentencias Ejecutadas / Sentencias Totales) × 100%
Ejemplo:
function calculateDiscount(price, isPremium, quantity) {
let discount = 0; // Sentencia 1
if (isPremium) { // Sentencia 2
discount = 0.20; // Sentencia 3
}
if (quantity > 10) { // Sentencia 4
discount += 0.10; // Sentencia 5
}
const finalPrice = price * (1 - discount); // Sentencia 6
return finalPrice; // Sentencia 7
}
Sentencias totales: 7
Caso de Prueba 1: calculateDiscount(100, true, 15)
Ejecuta: 1, 2, 3, 4, 5, 6, 7 (todas las 7 sentencias)
Cobertura: 100%
También podría lograrse 100% con:
Caso de Prueba 2: calculateDiscount(100, false, 5)
Ejecuta: 1, 2, 4, 6, 7 (omite 3 y 5)
Caso de Prueba 3: calculateDiscount(100, true, 15)
Ejecuta: 1, 2, 3, 4, 5, 6, 7
Ambos casos de prueba juntos: 100% cobertura de sentencias
Limitaciones:
- No asegura que todas las rutas estén probadas
- No prueba todas las condiciones
- 100% cobertura de sentencias ≠ código sin bugs
2. Cobertura de Ramas (Cobertura de Decisión)
Objetivo: Ejecutar cada rama (verdadera y falsa) de cada punto de decisión.
Fórmula: Cobertura de Ramas = (Ramas Ejecutadas / Ramas Totales) × 100%
Ejemplo:
function validateAge(age) {
if (age < 0) { // Decisión 1: Rama A (verdadero) / Rama B (falso)
return "Edad inválida";
}
if (age < 18) { // Decisión 2: Rama C (verdadero) / Rama D (falso)
return "Menor";
}
return "Adulto";
}
Ramas totales: 4 (A, B, C, D)
Caso de Prueba 1: validateAge(-5)
Ruta: A → return
Ramas cubiertas: A
Cobertura: 25%
Caso de Prueba 2: validateAge(15)
Ruta: B → C → return
Ramas cubiertas: B, C
Cobertura: 50%
Caso de Prueba 3: validateAge(25)
Ruta: B → D → return
Ramas cubiertas: B, D
Cobertura: 50%
Casos de Prueba 1, 2, 3 juntos:
Ramas cubiertas: A, B, C, D
Cobertura: 100%
La cobertura de ramas subsume la cobertura de sentencias: 100% cobertura de ramas garantiza 100% cobertura de sentencias, pero no viceversa.
3. Cobertura de Condición
Objetivo: Probar cada condición en una decisión independientemente para resultados verdaderos y falsos.
Ejemplo:
function canApprove(age, income, creditScore) {
// Decisión con 3 condiciones
if (age >= 18 && income >= 50000 && creditScore >= 700) {
return "Aprobado";
}
return "Rechazado";
}
Condiciones:
C1: age >= 18
C2: income >= 50000
C3: creditScore >= 700
Para 100% cobertura de condición, necesita:
- C1 verdadero y C1 falso
- C2 verdadero y C2 falso
- C3 verdadero y C3 falso
Casos de prueba:
TC1: (25, 60000, 750) → C1=V, C2=V, C3=V → Aprobado
TC2: (16, 60000, 750) → C1=F, C2=V, C3=V → Rechazado
TC3: (25, 40000, 750) → C1=V, C2=F, C3=V → Rechazado
TC4: (25, 60000, 650) → C1=V, C2=V, C3=F → Rechazado
Todas las condiciones probadas para verdadero y falso: 100% cobertura de condición
4. Cobertura de Múltiples Condiciones (MCC)
Objetivo: Probar todas las combinaciones posibles de condiciones.
Ejemplo:
if (A && B) {
// hacer algo
}
Combinaciones necesarias:
A=V, B=V → verdadero && verdadero = verdadero
A=V, B=F → verdadero && falso = falso
A=F, B=V → falso && verdadero = falso
A=F, B=F → falso && falso = falso
4 casos de prueba para 2 condiciones
Para 3 condiciones: 2³ = 8 combinaciones
Para 4 condiciones: 2⁴ = 16 combinaciones
Desafío: Crecimiento exponencial con número de condiciones hace esto impracticable para decisiones complejas.
Modified Condition/Decision Coverage (MC/DC): Alternativa más práctica que prueba el efecto independiente de cada condición en el resultado. Requerido para software crítico de seguridad (aviación, médico).
5. Cobertura de Ruta
Objetivo: Ejecutar cada ruta posible a través del código.
Ejemplo:
function processOrder(quantity, isPremium) {
let discount = 0;
if (quantity > 10) { // Punto de Decisión 1
discount = 0.10;
}
if (isPremium) { // Punto de Decisión 2
discount += 0.15;
}
return calculatePrice(quantity, discount);
}
Rutas posibles:
Ruta 1: D1=F, D2=F (quantity≤10, no premium)
Ruta 2: D1=F, D2=V (quantity≤10, premium)
Ruta 3: D1=V, D2=F (quantity>10, no premium)
Ruta 4: D1=V, D2=V (quantity>10, premium)
Casos de prueba para 100% cobertura de ruta:
TC1: (5, false) → Ruta 1
TC2: (5, true) → Ruta 2
TC3: (15, false) → Ruta 3
TC4: (15, true) → Ruta 4
Con bucles:
for (let i = 0; i < n; i++) {
// cuerpo del bucle
}
Rutas posibles:
- n = 0: Omitir bucle completamente
- n = 1: Ejecutar una vez
- n = 2: Ejecutar dos veces
- ...
- n = infinito: Teóricamente rutas infinitas
Enfoque práctico:
- Cero iteraciones
- Una iteración
- Múltiples iteraciones
- Máximas iteraciones (si está definido)
La cobertura de ruta es a menudo imposible para aplicaciones del mundo real debido a bucles y llamadas recursivas que crean rutas infinitas.
6. Testing de Bucles
Enfoque en bucles específicamente:
Bucles simples (bucle único):
for (let i = 0; i < n; i++) {
// procesar
}
Casos de prueba:
1. Omitir bucle (n = 0)
2. Una iteración (n = 1)
3. Dos iteraciones (n = 2)
4. Iteraciones típicas (n = valor medio)
5. Máximo-1 iteraciones (n = max-1)
6. Máximas iteraciones (n = max)
7. Exceder máximo (n = max+1)
Bucles anidados:
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
// procesar
}
}
Casos de prueba:
- Bucle interno con externo en mínimo/típico/máximo
- Bucle externo con interno en mínimo/típico/máximo
- Ambos en límites
Bucles concatenados (bucles independientes en secuencia):
for (let i = 0; i < m; i++) {
// procesar
}
for (let j = 0; j < n; j++) {
// procesar
}
Probar cada bucle independientemente usando pruebas de bucle simple
Herramientas de Cobertura de Código
Herramientas populares:
JavaScript/TypeScript:
- Istanbul/nyc
- Jest (cobertura integrada)
- Codecov
Java:
- JaCoCo
- Cobertura
- Clover
Python:
- Coverage.py
- pytest-cov
C#/.NET:
- OpenCover
- dotCover
- Coverlet
.NET Core/C++:
- gcov/lcov
- Bullseye Coverage
Ejemplo: Reporte de cobertura de Jest:
npm test -- --coverage
File | % Stmts | % Branch | % Funcs | % Lines |
---------------|---------|----------|---------|---------|
calculator.js | 94.44 | 83.33 | 100 | 93.75 |
validator.js | 100 | 100 | 100 | 100 |
utils.js | 88.89 | 75 | 90 | 88.24 |
---------------|---------|----------|---------|---------|
All files | 93.52 | 85.19 | 96.67 | 92.86 |
White Box Testing: Ventajas y Desventajas
Ventajas:
✓ Encuentra errores ocultos
✓ Optimiza código
✓ Mide exhaustividad de pruebas (métricas de cobertura)
✓ Prueba lógica compleja exhaustivamente
✓ Encuentra código muerto
✓ Permite automatización de pruebas
✓ Mejora calidad de código
Desventajas:
✗ Requiere habilidades de programación
✗ Consume tiempo
✗ Cambios de código rompen pruebas
✗ Puede perder funcionalidad faltante
✗ No puede comenzar hasta que exista código
✗ Potencialmente sesgado (desarrollador probando su propio código)
✗ Alto mantenimiento
Grey Box Testing: Lo Mejor de Ambos Mundos
¿Qué es Grey Box Testing?
Definición: Grey box testing combina enfoques de black box y white box. El tester tiene conocimiento parcial de la estructura interna—suficiente para diseñar mejores pruebas, pero aún prueba desde una perspectiva externa. Para más detalles sobre grey box testing, consulta nuestro artículo sobre testing de caja gris.
Características clave:
- Conocimiento parcial de internos
- Enfoque en integración entre componentes
- Prueba desde perspectiva de usuario con insight interno
- Acceso a diagramas de arquitectura, schemas de base de datos, algoritmos
- Acceso limitado o solo lectura al código
La perspectiva del tester:
Entrada → [CAJA GRIS] → Salida
(Conocimiento Parcial)
El tester conoce:
✓ Arquitectura de alto nivel
✓ Schema de base de datos
✓ Contratos de API
✓ Flujo de datos
✗ Detalles de implementación
✗ Código fuente completo
Cuándo Usar Grey Box Testing
Escenarios ideales:
- Integration testing: Probar interacciones de componentes
- Penetration testing: Testing de seguridad con conocimiento arquitectónico
- End-to-end testing: Con conocimiento de límites del sistema
- Database testing: Validar integridad de datos
- API testing: Con conocimiento de estructura backend
- Performance testing: Entender cuellos de botella
Quién lo realiza:
- Ingenieros de QA experimentados
- SDET (Software Development Engineers in Test)
- Ingenieros DevOps
- Testers de seguridad
- Cualquiera con conocimiento técnico pero perspectiva externa
Técnicas de Grey Box Testing
1. Testing de Matriz
Definir combinaciones de estado y entrada basándose en conocimiento interno de gestión de estado.
Ejemplo: Carrito de compras
Conocimiento de arquitectura:
- Carrito almacenado en sesión
- Artículos almacenados en base de datos
- Precios calculados server-side
Matriz de prueba:
Estado Usuario | Acción | Resultado Esperado
---------------|------------------|-----------------
Invitado | Agregar artículo | Carrito de sesión creado
Invitado | Ver carrito | Carrito de sesión mostrado
Invitado | Checkout | Redirigir a login
Autenticado | Agregar artículo | Carrito BD actualizado
Autenticado | Ver carrito | Carrito BD mostrado
Autenticado | Checkout | Proceder a pago
Expirado | Agregar artículo | Sesión renovada
Expirado | Ver carrito | Re-autenticar
2. Testing de Patrones
Usar conocimiento de patrones de diseño comunes para enfocar testing.
Ejemplo: Sabiendo que el sistema usa patrón Repository
Áreas de enfoque de prueba:
- Consistencia de operaciones CRUD
- Manejo de transacciones
- Manejo de excepciones en repository
- Connection pooling
- Comportamiento de caché
En lugar de probar ciegamente todas las operaciones,
enfocarse en preocupaciones específicas del patrón.
3. Testing de Arreglo Ortogonal
Diseñar combinaciones de prueba eficientes usando conocimiento de interacciones de parámetros.
Ejemplo: Aplicación web con múltiples variables
Variables (del conocimiento de arquitectura):
- Navegador: Chrome, Firefox, Safari
- SO: Windows, Mac, Linux
- Base de Datos: MySQL, PostgreSQL
- Caché: On, Off
Combinación completa: 3 × 3 × 2 × 2 = 36 pruebas
Usando arreglo ortogonal (L9):
Prueba | Navegador | SO | BD | Caché
-------|-----------|---------|-------|-------
1 | Chrome | Windows | MySQL | On
2 | Chrome | Mac | Postgres | Off
3 | Chrome | Linux | MySQL | Off
4 | Firefox | Windows | Postgres | On
5 | Firefox | Mac | MySQL | Off
6 | Firefox | Linux | Postgres | On
7 | Safari | Windows | MySQL | Off
8 | Safari | Mac | Postgres | On
9 | Safari | Linux | MySQL | On
9 pruebas en lugar de 36, con buena cobertura de interacciones
Grey Box Testing: Ventajas y Desventajas
Ventajas:
✓ Mejor diseño de prueba que black box puro
✓ Más eficiente que white box puro
✓ Encuentra problemas de integración
✓ Escenarios de testing realistas
✓ Enfoque balanceado
✓ Bueno para testing de seguridad
✓ Identifica problemas arquitectónicos
Desventajas:
✗ Requiere conocimiento técnico
✗ Diseño de prueba más complejo
✗ Puede aún perder bugs internos
✗ Requiere acceso a docs arquitectónicos
✗ Puede ser inconsistente (depende de cuánto se conoce)
Eligiendo el Enfoque Correcto
Marco de Decisión
Usar Black Box cuando:
✓ Probando desde perspectiva del usuario
✓ Testers no tienen habilidades de codificación
✓ Probando software de terceros
✓ Código aún no disponible
✓ Testing basado en requisitos
✓ Acceptance testing
✓ System testing de alto nivel
Usar White Box cuando:
✓ Unit testing de funciones/métodos
✓ Encontrar vulnerabilidades de seguridad
✓ Optimizar rendimiento
✓ Probar algoritmos complejos
✓ Necesitar métricas de cobertura de código
✓ Developer testing
✓ Encontrar código muerto
Usar Grey Box cuando:
✓ Integration testing
✓ API testing
✓ Database testing
✓ Security/penetration testing
✓ End-to-end testing con insight técnico
✓ Probar sistemas distribuidos
✓ Microservices testing
Combinando Enfoques: La Pirámide
▲
╱ ╲
╱ ╲ Exploratorio Manual (Grey/Black)
╱ ╲
╱───────╲
╱ ╲
╱ Pruebas E2E ╲ (Grey/Black Box)
╱ (UI/API) ╲
╱────────────────╲
╱ ╲
╱ Pruebas Integración ╲ (Grey Box)
╱ ╲
╱────────────────────────╲
╱ ╲
╱ Pruebas Unitarias ╲ (White Box)
╱ ╲
╱──────────────────────────────╲
Base: Muchas pruebas unitarias white box rápidas
Medio: Pruebas de integración grey box
Superior: Menos pruebas E2E black/grey box
Cima: Testing exploratorio manual
Ejemplo del Mundo Real: Checkout E-commerce
Black box testing:
Escenarios de prueba:
- Flujo de checkout invitado
- Checkout de usuario registrado
- Aplicar código de cupón
- Cambiar dirección de envío
- Tarjeta de pago inválida
- Email de confirmación de pedido
Enfoque: Flujos de trabajo de usuario
Perspectiva: Externa
Técnicas: Testing de caso de uso, análisis de valores límite
White box testing:
Escenarios de prueba:
- Algoritmo de cálculo de precio
- Lógica de cálculo de impuestos
- Orden de aplicación de descuento
- Manejo de error de procesamiento de pago
- Rollback de transacción de base de datos
- Momento de deducción de inventario
Enfoque: Lógica interna
Perspectiva: Nivel de código
Técnicas: Cobertura de sentencias, cobertura de ramas, testing de ruta
Grey box testing:
Escenarios de prueba:
- Integración de gateway de pago
- Transiciones de estado de pedido en base de datos
- Invalidación de caché en cambios de precio
- Cola de mensajes para procesamiento de pedido
- Violaciones de restricciones de base de datos
- Flujos de autenticación de API
Enfoque: Interacciones de componentes
Perspectiva: Arquitectónica
Técnicas: Integration testing, API testing, database testing
Mejores Prácticas en Todos los Enfoques
1. Usar la Herramienta Correcta para el Trabajo
✓ No forzar un enfoque para todo
✓ Combinar enfoques estratégicamente
✓ Hacer coincidir técnica con lo que estás probando
✓ Considerar habilidades del tester y restricciones del proyecto
2. Automatizar Apropiadamente
Pruebas unitarias white box: Altamente automatizadas
Pruebas de integración grey box: Mayormente automatizadas
Pruebas E2E black box: Selectivamente automatizadas
Black/grey box exploratorio: Manual
3. Medir lo que Importa
Métricas black box:
- Cobertura de requisitos
- Cobertura de escenarios de usuario
- Tasa de descubrimiento de defectos
Métricas white box:
- Cobertura de código (sentencia, rama)
- Complejidad ciclomática
- Code churn
Métricas grey box:
- Cobertura de puntos de integración
- Cobertura de endpoints de API
- Cobertura de flujo de datos
4. Documentar tu Testing
Black box:
- Casos de prueba vinculados a requisitos
- Resultados esperados vs actuales
- Escenarios de usuario
White box:
- Reportes de cobertura
- Rutas de código probadas
- Áreas no probadas y por qué
Grey box:
- Escenarios de prueba de integración
- Diagramas de interacción de componentes
- Mapas de flujo de datos
5. Mejora Continua
✓ Revisar efectividad de pruebas
✓ Analizar defectos escapados
✓ Refinar técnicas
✓ Compartir conocimiento entre equipo
✓ Actualizar estrategia de prueba a medida que evoluciona sistema
Errores Comunes a Evitar
Errores de black box:
✗ Sobre-confianza sin considerar internos
✗ Pruebas redundantes por falta de conocimiento de código
✗ Perder escenarios internos críticos
✗ Testing de límites débil
✗ Ignorar condiciones de error
Errores de white box:
✗ Perseguir 100% cobertura sin calidad
✗ Pruebas frágiles que se rompen en refactorización
✗ Probar implementación en lugar de comportamiento
✗ Sesgo del desarrollador (probando para pasar)
✗ Descuidar perspectiva del usuario
Errores de grey box:
✗ Conocimiento inconsistente entre testers
✗ Sobre-complicar escenarios de prueba simples
✗ Acceso a código tentando enfoque white box
✗ Falta de límites claros
✗ Asumir que conocimiento arquitectónico está actualizado
Conclusión
Black box, white box y grey box testing no son enfoques competidores—son perspectivas complementarias que, cuando se usan juntas, crean una estrategia de testing completa.
Recuerda:
- Black box asegura que el sistema hace lo que los usuarios necesitan
- White box asegura que el sistema lo hace correctamente internamente
- Grey box asegura que los componentes trabajan juntos apropiadamente
Las estrategias de testing más efectivas combinan los tres enfoques, aplicando cada uno donde proporciona más valor. Comienza con una base sólida de pruebas unitarias white box, construye pruebas de integración grey box que verifiquen interacciones de componentes, agrega pruebas de sistema black box que validen escenarios de usuario, y remata con testing exploratorio manual que ejercite creatividad e intuición.
Al entender cuándo y cómo usar cada enfoque, construirás software que no solo es funcionalmente correcto, sino robusto, performante, seguro y encantador de usar.
Lecturas Adicionales
- “Software Testing Techniques” de Boris Beizer
- “The Art of Software Testing” de Glenford Myers
- “How Google Tests Software” de James Whittaker
- Syllabus ISTQB secciones sobre técnicas de prueba
- Estándar IEEE 829 para Documentación de Prueba de Software