ATDD invierte el orden habitual: QA escribe un test de aceptación en Playwright antes de que exista la funcionalidad, el test falla, y la funcionalidad está terminada cuando el test pasa. Ese único cambio mueve a QA de verificar trabajo terminado a definir qué significa "terminado". Este artículo cubre el ciclo Rojo-Verde-Refactor, cómo el formato Given/When/Then de BDD encaja en el flujo de trabajo de los tres amigos, y qué cambia en el día a día de QA cuando los desarrolladores ya practican TDD.
El ciclo TDD: Rojo, Verde, Refactor
TDD sigue un ciclo estricto de tres pasos:
1. Rojo: escribir un test que falle (porque la funcionalidad todavía no existe)
2. Verde: escribir el código mínimo para que el test pase
3. Refactor: limpiar el código manteniendo los tests en verde
Este ciclo se repite para cada pequeña pieza de funcionalidad.
// Fase rojo: escribir un test que falle
test('calculateDiscount aplica 10% para el código SAVE10', () => {
const result = calculateDiscount(100, 'SAVE10');
expect(result).toBe(90);
});
// Ejecutar este test falla: calculateDiscount no está definida// Fase verde: escribir el código mínimo para pasar
function calculateDiscount(price: number, code: string): number {
if (code === 'SAVE10') {
return price * 0.9;
}
return price;
}
// Ahora el test pasa// Fase refactor: limpiar sin romper el test
const DISCOUNT_CODES: Record<string, number> = {
SAVE10: 0.1,
SAVE20: 0.2,
SAVE50: 0.5,
};
function calculateDiscount(price: number, code: string): number {
const discount = DISCOUNT_CODES[code] || 0;
return price * (1 - discount);
}
// Los tests siguen pasando: el refactor no rompió nadaBeneficios de TDD que afectan a QA
Código naturalmente testeable
El código escrito con TDD tiende a tener funciones más pequeñas con entradas y salidas claras, más fácil de probar a todos los niveles.
Seguridad ante regresiones
Cada comportamiento está protegido por un test. Cuando QA encuentra un bug, los desarrolladores pueden reproducirlo con un test, corregirlo, y el test previene regresiones.
Documentación a través de tests
Los tests TDD describen qué debería hacer el código en escenarios específicos. QA puede leer los tests para entender el comportamiento esperado.
Detección temprana de bugs
Los problemas detectados al escribir tests unitarios son órdenes de magnitud más baratos de corregir que los encontrados en QA o en producción.
Desarrollo guiado por comportamiento (BDD)
BDD extiende TDD hacia la capa de negocio. Donde TDD se enfoca en cómo funciona el código, BDD se enfoca en qué comportamiento se requiere.
Los tres amigos: desarrollador, QA y product manager colaboran para definir comportamientos usando el formato Given/When/Then antes de escribir cualquier código.
Feature: Códigos de descuento
Scenario: Un código de descuento válido reduce el precio
Given tengo un carrito con artículos por un total de $100
When aplico el código de descuento "SAVE10"
Then el total debería ser $90
And el monto de descuento debería ser $10
Scenario: Un código de descuento inválido muestra error
Given tengo un carrito con artículos por un total de $100
When aplico el código de descuento "INVALID"
Then debería ver "Código de descuento inválido"
And el total debería seguir siendo $100
Scenario: Un código de descuento vencido muestra error
Given tengo un carrito con artículos por un total de $100
When aplico el código de descuento "EXPIRED20"
Then debería ver "Este código de descuento ha vencido"Cómo QA puede aplicar la mentalidad TDD
Aunque no estés escribiendo tests unitarios, puedes aplicar la mentalidad TDD.
Escribir casos de prueba antes de que empiece el testing manual
En lugar de hacer testing exploratorio desde cero, escribe primero los comportamientos esperados:
Funcionalidad: Reseteo de contraseña
Lo que espero que sea verdad:
1. Ingresar un email válido envía un email de reseteo en 2 minutos
2. Ingresar un email inválido muestra "Email no encontrado"
3. El enlace de reseteo vence después de 24 horas
4. Usar un enlace vencido muestra "Enlace vencido" con opción de solicitar uno nuevo
5. Después de un reseteo exitoso, la contraseña anterior ya no funciona
6. El enlace de reseteo solo puede usarse una vezYa tienes un plan de pruebas antes de empezar a probar.
Desarrollo guiado por tests de aceptación (ATDD)
Colabora con los desarrolladores para escribir tests de aceptación antes de que se construya la funcionalidad:
// Escrito antes de que exista la funcionalidad
test('el checkout con tarjeta válida completa la compra', async ({ page }) => {
// Configuración: usuario con artículos en el carrito
// ...
// Ejecutar checkout
await page.fill('[data-testid="card-number"]', '4242 4242 4242 4242');
await page.fill('[data-testid="card-expiry"]', '12/28');
await page.fill('[data-testid="card-cvc"]', '123');
await page.click('[data-testid="pay-now"]');
// Resultados esperados
await expect(page).toHaveURL('/order-confirmation');
await expect(page.getByTestId('order-number')).toBeVisible();
await expect(page.getByTestId('success-message')).toContainText('Pago exitoso');
});Estos tests fallan hasta que se construye la funcionalidad. Cuando pasan, la funcionalidad está terminada.
Cuando los desarrolladores practican TDD: qué necesita saber QA
Qué cambia para QA
#### La cobertura de tests unitarios ya existe
Los desarrolladores ya probaron los casos extremos a nivel de código. QA puede enfocarse en los puntos de integración, los flujos de usuario y la lógica de negocio, no en el comportamiento básico de las funciones.
#### Los fallos de tests son significativos
Cuando el CI de un equipo TDD falla, es específico. "La función X devuelve un valor incorrecto para el caso extremo Y", no "la app está rota en algún lugar".
#### El refactor es más seguro
Con tests unitarios completos, QA no necesita volver a probar funcionalidad básica después de un refactor: los tests ya la cubren.
Lo que QA todavía necesita hacer
#### Testing de integración
Los tests unitarios prueban funciones en aislamiento. QA prueba cómo trabajan juntos los componentes: la base de datos, la API, el frontend, el sistema de email.
#### Testing desde la perspectiva del usuario
Los desarrolladores prueban "¿funciona el código?". QA prueba "¿tiene sentido usar esta funcionalidad?".
#### Descubrimiento de casos extremos
El testing exploratorio de QA encuentra escenarios que no se especificaron. TDD solo cubre lo que se pensó al escribir los tests.
#### Rendimiento y confiabilidad
TDD no cubre tiempos de respuesta, usuarios concurrentes ni qué pasa bajo carga.
TDD práctico para automatización de tests
Al construir tu framework de tests, aplica los principios TDD:
// En lugar de escribir el helper completo primero, escribí un test para lo que querés que haga
test('el helper de login debería redirigir al dashboard después del login', async ({ page }) => {
await loginAs(page, 'member'); // Esta función todavía no existe
await expect(page).toHaveURL('/dashboard');
});
// Ahora escribí la implementación mínima
async function loginAs(page: Page, role: 'admin' | 'member') {
const credentials = {
admin: { email: 'admin@test.com', password: 'AdminPass1' },
member: { email: 'member@test.com', password: 'MemberPass1' },
};
await page.goto('/login');
await page.fill('[data-testid="email"]', credentials[role].email);
await page.fill('[data-testid="password"]', credentials[role].password);
await page.click('[data-testid="submit"]');
await page.waitForURL('/dashboard');
}Esto previene el sobreingeniering. Construyes exactamente lo que se necesita, y el test confirma que funciona.
La pirámide de testing en el contexto TDD
TDD da forma directamente a la pirámide de testing:
/\
/E2E\ ← Automatización QA (pocos, lentos)
/------\
/ Integr.\ ← Tests de integración (moderados)
/----------\
/ Tests Unit.\ ← Output de TDD (muchos, rápidos)
/--------------\TDD produce la base amplia de tests unitarios. QA construye las capas de integración y E2E encima. Juntas forman una pirámide donde la mayoría de los bugs se detectan barato a nivel unitario, con un conjunto pequeño y enfocado de tests E2E costosos.
→ See also: Desarrollo Guiado por Tests: La Guía del Ingeniero QA | Testing Shift-Left: Qué Significa y Cómo Practicarlo | La Pirámide de Tests Explicada para Ingenieros QA