Passer au contenu principal

🧪 Développement Piloté par les Tests (TDD)

📖 Définition

TDD (Test-Driven Development) est une méthodologie de développement où vous écrivez d'abord les tests, puis écrivez du code pour réussir ces tests. Il suit le cycle Rouge-Vert-Refactor, améliorant la qualité du code, réduisant les bugs et rendant le refactoring plus sûr. Les tests unitaires vérifient les fonctions ou composants individuels de manière indépendante.

🎯 Analogie Simple

Plan d'Abord

Développement Traditionnel
1. Construire une maison
2. Vérifier après achèvement
3. Trouver des problèmes → Grandes corrections
4. Coût augmente

TDD
1. Dessiner un plan (Écrire un test)
2. Construire selon le plan (Écrire du code)
3. Vérifier (Exécuter le test)
4. Améliorer (Refactoriser)
5. Sûr et précis

⚙️ Fonctionnement

Cycle TDD (Rouge-Vert-Refactor)

🔴 Rouge (Échec)
└─ Écrire un test → Échec (pas de code)

🟢 Vert (Succès)
└─ Écrire un code minimal → Test réussit

🔵 Refactor (Améliorer)
└─ Améliorer le code → Test réussit toujours

Répéter → Amélioration progressive

💡 Exemples Clés

Exemple TDD de Base

// ========== 1. Rouge: Écrire un test (échoue) ==========
test('la fonction add additionne deux nombres', () => {
expect(add(2, 3)).toBe(5);
});
// FAIL - add n'est pas défini

// ========== 2. Vert: Code minimal (réussit) ==========
function add(a, b) {
return a + b;
}
// PASS ✅

// ========== 3. Refactor: Améliorer (si nécessaire) ==========
// Le code est simple, pas d'amélioration nécessaire

Test Unitaire avec 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('Jean', 'jean@example.com');
});

test('devrait retourner true pour un email valide', () => {
expect(user.isValidEmail()).toBe(true);
});

test('devrait retourner false pour un email invalide', () => {
user.email = 'invalid-email';
expect(user.isValidEmail()).toBe(false);
});
});

Test Asynchrone

test('fonction async retourne des données', async () => {
const data = await fetchData();
expect(data).toEqual({ name: 'John' });
});

Mocking

// Mock de fonction
const mockCallback = jest.fn(x => x * 2);

[1, 2, 3].forEach(mockCallback);

expect(mockCallback).toHaveBeenCalledTimes(3);

// Mock de module
jest.mock('axios');

test('fetchUser retourne les données utilisateur', async () => {
axios.get.mockResolvedValue({ data: { id: 1 } });
const user = await fetchUser(1);
expect(user).toEqual({ id: 1 });
});

🤔 FAQ

Q1. Avantages de TDD ?

R:

Avantages:
1. Moins de bugs
2. Refactoring sûr
3. Meilleure qualité de code
4. Documentation
5. Confiance

Inconvénients:
1. Investissement de temps initial
2. Courbe d'apprentissage
3. Maintenance des tests

Conclusion: Gain à long terme

Q2. Que Tester ?

R:

// ✅ Devrait tester
1. Logique métier
2. Cas limites
3. Gestion des erreurs
4. APIs publiques

// ❌ Pas besoin de tester
1. Bibliothèques externes
2. Getters/setters simples
3. Détails d'implémentation privée

Q3. Objectif de Couverture ?

R:

# Mesurer la couverture
npm test -- --coverage

# Objectif:
80%+ couverture // Objectif réaliste
100% couverture // Idéal mais peu pratique

# Rappelez-vous:
Haute couverture ≠ Bons tests
Les tests significatifs comptent !

🎬 Résumé

TDD est la base de la qualité logicielle :

  • Rouge-Vert-Refactor: Cycle central de TDD
  • Tests Unitaires: Rapides et isolés
  • Test d'Abord: Les tests guident la conception
  • Amélioration Continue: Filet de sécurité pour le refactoring

Les tests sont un investissement pour votre futur vous ! 🧪✨