🧪 Desarrollo Dirigido por Pruebas (TDD)
📖 Definición
TDD (Test-Driven Development) es una metodología de desarrollo donde escribes pruebas primero, luego escribes código para pasar esas pruebas. Sigue el ciclo Rojo-Verde-Refactor, mejorando la calidad del código, reduciendo errores y haciendo que la refactorización sea más segura. Las pruebas unitarias verifican funciones o componentes individuales de forma independiente.
🎯 Analogía Simple
Plano Primero
Desarrollo Tradicional
1. Construir casa
2. Verificar después de completar
3. Encontrar problemas → Grandes correcciones
4. Costo aumenta
TDD
1. Dibujar plano (Escribir prueba)
2. Construir según plano (Escribir código)
3. Verificar (Ejecutar prueba)
4. Mejorar (Refactorizar)
5. Seguro y preciso
⚙️ Cómo Funciona
Ciclo TDD (Rojo-Verde-Refactor)
🔴 Rojo (Falla)
└─ Escribir prueba → Falla (sin código)
🟢 Verde (Pasa)
└─ Escribir código mínimo → Prueba pasa
🔵 Refactor (Mejorar)
└─ Mejorar código → Prueba sigue pasando
Repetir → Mejora gradual
💡 Ejemplos Clave
Ejemplo Básico de TDD
// ========== 1. Rojo: Escribir prueba (falla) ==========
test('función add suma dos números', () => {
expect(add(2, 3)).toBe(5);
});
// FAIL - add no está definida
// ========== 2. Verde: Código mínimo (pasa) ==========
function add(a, b) {
return a + b;
}
// PASS ✅
// ========== 3. Refactor: Mejorar (si es necesario) ==========
// El código es simple, no se necesita mejora
Prueba Unitaria con Jest
// user.js
class User {
constructor(name, email) {
this.name = name;
this.email = email;
}
isValidEmail() {
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
return emailRegex.test(this.email);
}
}
// user.test.js
describe('User', () => {
let user;
beforeEach(() => {
user = new User('Juan', 'juan@example.com');
});
test('debe retornar true para email válido', () => {
expect(user.isValidEmail()).toBe(true);
});
test('debe retornar false para email inválido', () => {
user.email = 'invalid-email';
expect(user.isValidEmail()).toBe(false);
});
});
Prueba Asíncrona
test('función async retorna datos', async () => {
const data = await fetchData();
expect(data).toEqual({ name: 'John' });
});
Mocking
// Mock de función
const mockCallback = jest.fn(x => x * 2);
[1, 2, 3].forEach(mockCallback);
expect(mockCallback).toHaveBeenCalledTimes(3);
// Mock de módulo
jest.mock('axios');
test('fetchUser retorna datos de usuario', async () => {
axios.get.mockResolvedValue({ data: { id: 1 } });
const user = await fetchUser(1);
expect(user).toEqual({ id: 1 });
});
🤔 Preguntas Frecuentes
P1. ¿Beneficios de TDD?
R:
Pros:
1. Menos errores
2. Refactorización segura
3. Mejor calidad de código
4. Documentación
5. Confianza
Contras:
1. Inversión de tiempo inicial
2. Curva de aprendizaje
3. Mantenimiento de pruebas
Conclusión: Ganancia a largo plazo
P2. ¿Qué Probar?
R:
// ✅ Debe probar
1. Lógica de negocio
2. Casos extremos
3. Manejo de errores
4. APIs públicas
// ❌ No necesita probar
1. Bibliotecas externas
2. Getters/setters simples
3. Detalles de implementación privada
P3. ¿Objetivo de Cobertura?
R:
# Medir cobertura
npm test -- --coverage
# Objetivo:
80%+ cobertura // Objetivo realista
100% cobertura // Ideal pero poco práctico
# Recuerde:
Alta cobertura ≠ Buenas pruebas
¡Las pruebas significativas importan!
🎬 Resumen
TDD es la base de la calidad del software:
- Rojo-Verde-Refactor: Ciclo central de TDD
- Pruebas Unitarias: Rápidas y aisladas
- Prueba Primero: Las pruebas guían el diseño
- Mejora Continua: Red de seguridad para refactorización
¡Las pruebas son una inversión en tu yo futuro! 🧪✨