Le Test-Driven Development (TDD) est une pratique qui divise encore aujourd'hui. Considéré par certains comme une perte de temps et par d'autres comme une discipline essentielle pour produire un code robuste, il est souvent mal compris. Alors, est-ce vraiment compliqué de bien faire du TDD ? Spoiler : non, mais cela demande une méthodologie rigoureuse et un peu d’entraînement.

Dans cet article, nous allons explorer l’état de l’art du TDD en 2024, en vous donnant des exemples concrets pour Node.js, Angular, et React, tout en vous offrant des pistes pour approfondir cette discipline.


📜 Les principes fondamentaux du TDD

Le TDD repose sur un cycle itératif en trois étapes appelé Red-Green-Refactor :

  1. Red : Écrivez un test qui échoue. Cela garantit que le test est valide et qu'aucune fonctionnalité n'existe encore.
  2. Green : Implémentez le code minimum nécessaire pour que le test passe.
  3. Refactor : Améliorez le code sans casser le test, en veillant à ce qu'il reste lisible et maintenable.

Pourquoi adopter le TDD ?

  • Qualité accrue : Réduisez les bugs en validant chaque fonctionnalité dès sa création.
  • Documentation vivante : Les tests servent de guide pour comprendre ce que fait le code.
  • Confiance lors des modifications : Un filet de sécurité solide permet des refactorisations sereines.

🌍 TDD avec Node.js

Node.js est une plateforme idéale pour pratiquer le TDD, grâce à ses outils simples et efficaces.

Outils recommandés :

  • Mocha : Un framework de test flexible. Lien
  • Chai : Une librairie d'assertions. Lien
  • Jest : Une alternative tout-en-un, parfaite pour les projets modernes. Lien

Exemple simple :

Prenons une fonction qui calcule la somme de deux nombres :

  1. Écrire un test (Red) :
   const { expect } = require('chai');
   const sum = require('./sum');

   describe('Sum function', () => {
     it('should return the sum of two numbers', () => {
       expect(sum(1, 2)).to.equal(3);
     });
   });
  1. Faire passer le test (Green) :
   function sum(a, b) {
     return a + b;
   }
   module.exports = sum;
  1. Refactoriser (Refactor) : Dans cet exemple simple, il n'y a pas grand-chose à améliorer, mais dans des cas complexes, cela pourrait inclure le nettoyage ou l'optimisation du code.

🖼️ TDD avec Angular

Angular facilite le TDD grâce à son environnement intégré et son générateur de tests. Les fichiers .spec.ts sont générés automatiquement, ce qui rend la mise en œuvre rapide et intuitive.

Outils recommandés :

  • Karma : Test runner par défaut d'Angular. Lien
  • Jasmine : Librairie d'assertions incluse dans Angular CLI. Lien

Exemple : Tester un service Angular

Supposons que vous ayez un service pour récupérer des données utilisateur :

  1. Écrire un test (Red) :
   import { TestBed } from '@angular/core/testing';
   import { UserService } from './user.service';

   describe('UserService', () => {
     let service: UserService;

     beforeEach(() => {
       TestBed.configureTestingModule({});
       service = TestBed.inject(UserService);
     });

     it('should fetch user data', () => {
       const user = service.getUser();
       expect(user).toEqual({ id: 1, name: 'John Doe' });
     });
   });
  1. Faire passer le test (Green) :
   import { Injectable } from '@angular/core';

   @Injectable({
     providedIn: 'root',
   })
   export class UserService {
     getUser() {
       return { id: 1, name: 'John Doe' };
     }
   }
  1. Refactoriser (Refactor) : Si les données utilisateur proviennent d’une API, vous pourriez externaliser la logique dans un autre service ou mocker les données pour des tests plus avancés.

⚛️ TDD avec React

React, avec son approche basée sur les composants, se prête particulièrement bien au TDD. Les tests de composants assurent que chaque partie de votre interface fonctionne indépendamment.

Outils recommandés :

  • Jest : Test runner complet avec des assertions et un simulateur DOM. Lien
  • React Testing Library : Testez vos composants comme un utilisateur réel. Lien

Exemple : Tester un composant React

Supposons que vous ayez un bouton qui incrémente un compteur.

  1. Écrire un test (Red) :
   import { render, screen, fireEvent } from '@testing-library/react';
   import Counter from './Counter';

   test('increments counter on button click', () => {
     render(<Counter />);
     const button = screen.getByText('Increment');
     fireEvent.click(button);
     expect(screen.getByText('Count: 1')).toBeInTheDocument();
   });
  1. Faire passer le test (Green) :
   import React, { useState } from 'react';

   function Counter() {
     const [count, setCount] = useState(0);

     return (
       <div>
         <p>Count: {count}</p>
         <button onClick={() => setCount(count + 1)}>Increment</button>
       </div>
     );
   }

   export default Counter;
  1. Refactoriser (Refactor) : Si votre composant devient complexe, vous pourriez externaliser la logique dans un hook personnalisé.

📚 Ressources pour aller plus loin

  • Livres :

  • Test-Driven Development: By Example de Kent Beck.

  • Clean Code de Robert C. Martin.

  • Tutoriels en ligne :

  • TDD avec Node.js

  • TDD avec Angular

  • TDD avec React

  • Communautés :

  • r/testing sur Reddit pour des discussions et des conseils.

  • Les forums StackOverflow avec le tag "tdd".


💡 En conclusion

Le TDD peut sembler intimidant au départ, mais en suivant une approche progressive et en s’appuyant sur les bons outils, il devient une méthode puissante pour produire du code fiable et maintenable. Alors, est-ce compliqué de bien faire du TDD ? Non, mais cela demande de la rigueur et une volonté d’apprendre. Prêt à relever le défi ? 🚀

Julien Moulin

Fondateur & Formateur Js/Ts

Julien Moulin est un expert en développement full stack (JS/TS) et un leader technique reconnu. Il excelle dans l'adoption de technologies innovantes tout en répondant aux besoins clients. Son approche allie pragmatisme et innovation, avec une expertise couvrant les plateformes e-commerce, les applications métiers et la modernisation des architectures existantes. En mentor passionné, il partage ses connaissances avec pédagogie, encourage l’apprentissage continu, et inspire ses équipes à relever des défis ambitieux.

Rien est impossible !