Le développement piloté par les tests (Test-Driven Development en anglais) est une approche agile du développement de logiciels qui met l'accent sur l'écriture itérative de tests et du code métier. Le processus TDD comprend trois (03) étapes :
écrire un test qui échoue avant d'écrire le code ;
interdire d'écrire un test plus compliqué que nécessaire ;
éviter d'écrire plus de code que nécessaire, mais seulement ce qu'il faut pour réussir le test qui a échoué.
Ces trois (03) règles fonctionnent ensemble dans le cadre d'un processus appelé le cycle rouge-vert-refactorisation (red-green-refactor en anglais).
Le processus TDD est itératif et implique l'écriture d'un test qui échoue, l'écriture du code pour réussir le test, puis le refactorisation du code pour améliorer sa conception et sa maintenabilité. Le processus est répété jusqu'à ce que le code soit complet. En écrivant d'abord les tests, la méthode TDD garantit que le code est correct et répond aux exigences définies dans les tests. Elle encourage également les développeurs à écrire un code propre, facile à maintenir, à modifier et à faire évoluer.
Dans cet article, nous allons nous concentrer sur l'introduction au TDD en utilisant Angular, un framework JavaScript populaire pour le développement d'applications web. Nous allons créer une application de calculatrice simple pour illustrer les concepts du TDD.
Étape 1: Création du projet Angular
Avant de commencer à développer notre application de calculatrice, nous devons naturellement créer notre projet en utilisant la commande suivante :
ng new calculator-app
Étape 2: Création du composant de calculatrice
Maintenant que notre projet est créé, nous pouvons commencer à développer notre application de calculatrice. Créez un nouveau composant de calculatrice en utilisant la commande suivante:
ng generate component calculator
Cette commande créera un nouveau dossier calculator
contenant les fichiers nécessaires pour notre composant de calculatrice. Nous travaillerons dans un premier temps dans le fichier calculator.component.spec.ts
.
Étape 3: Exploration du fichier calculator.component.spec.ts
Lorsque vous ouvrez le fichier, voici le code que vous avez par défaut :
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { CalculatorComponent } from './calculator.component';
describe('CalculatorComponent', () => {
let calculator: CalculatorComponent; // component a été remplacé par calculator
let fixture: ComponentFixture<CalculatorComponent>;
beforeEach(async () => {
await TestBed.configureTestingModule({
declarations: [ CalculatorComponent ]
})
.compileComponents();
fixture = TestBed.createComponent(CalculatorComponent);
calculator = fixture.componentInstance;
fixture.detectChanges();
});
it('should create', () => {
expect(calculator).toBeTruthy();
});
});
Dans le code généré ci-dessous, nous avons une suite de tests utilisant la fonction describe
, qui fournit un nom descriptif pour le composant testé. Dans la suite de tests, nous avons un bloc beforeEach
pour configurer l'environnement de test. La méthode TestBed.configureTestingModule
est utilisée pour configurer le module de test et fournir les dépendances nécessaires. La variable calculator
est ensuite assignée à une instance du CalculatorComponent
à l'aide de la méthode TestBed.inject
.
Etape 4: Ecriture de notre premier test
Notre composant CalculatorComponent
nous permettra d'effectuer des opérations arithmétiques de base. Pour écrire un test unitaire en utilisant le TDD, nous allons commencer par créer un scénario de test qui vérifie le comportement attendu du composant. Nous allons maintenant écrire le scénario de test proprement dit en utilisant la fonction it
. Dans ce cas, nous allons tester la méthode add
du CalculatorComponent
en lui passant deux nombres et en nous attendant à ce que le résultat soit 5
. La fonction expect
est utilisée pour définir le comportement attendu et vérifier le résultat réel. Ce code doit être ajouté à la suite de tests, c'est-à-dire à l'intérieur de la fonction describe
.
it('should add two numbers correctly', () => {
const result = calculator.add(2, 3);
expect(result).toBe(5);
});
Etape 4: Exécution du test
Avant même d'exécuter le test, vous obtenez une erreur dans votre éditeur de code vous indiquant que la fonction add n'existe pas.
C'est normal, puisqu'elle n'a pas encore été créée.
Ensuite, en retournant sur notre serveur Karma, nous constatons que notre test case n'est pas affiché dans
CalculatorComponent` et dans le terminal, nous avons une erreur liée à l'inexistence de la fonction et un message indiquant qu'aucun test n'a réussi.
Pas de panique, c'est le rouge du TDD ! Bravo 😂
Etape 5: Ecriture du code minimum pour que le test passe
Dans notre classe CalculatorComponent, en suivant l'approche TDD, nous allons écrire le minimum de code nécessaire pour que notre test précédemment écrit passe.
add(a: number, b: number): number {
return a + b;
}
Le résultat sur votre serveur Karma :
Et dans votre terminal :
Nous en sommes à l'étape
green
du TDD, c'est-à-dire que nous écrivons la quantité minimale de code nécessaire pour que notre test soit réussi.C'est très bien !
Etape 6: Refactoriser le code
Une fois les tests réussis, vous pouvez refactoriser le code pour en améliorer la conception, la lisibilité et la maintenabilité. La refactorisation est une étape essentielle du processus TDD, qui permet d'éliminer les doublons, d'améliorer la structure du code et la qualité globale. Il est essentiel de s'assurer que les tests continuent à fonctionner après la refactorisation. La révision et la mise à jour régulière des tests au fur et à mesure de l'évolution de la base de code contribueront à maintenir l'intégrité et la fiabilité des tests unitaires.
Maintenant, faites le même exercice pour rajouter les autres types d'opérations qu'on retrouve sur une calculatrice. Vous remarquerez que vous passez plus de temps dans votre éditeur de texte ou IDE que sur le navigateur et dans votre terminal. À aucun moment, vous n'avez eu besoin d'ouvrir votre navigateur sauf pour visualiser quoique ce soit à part le résultat du serveur Karma.
Pour plus d'informations :