BDD en TypeScript : quand le code parle le langage métier
\n\nAvez-vous déjà traduit un document d'exigences de plusieurs pages pour réaliser que le client voulait dire quelque chose de complètement différent ? La situation où le développeur et l'analyste regardent la même tâche mais voient deux applications différentes vous est-elle familière ? Si oui, vous êtes prêt pour le BDD (Behaviour-Driven Development) — une méthodologie qui efface la frontière entre « je veux » et « c'est fait ».
\n\nAujourd'hui, nous allons parler de la façon d'implémenter le BDD en TypeScript. Je vais vous montrer comment transformer des spécifications ennuyeuses en scénarios vivants et exécutables que comprendront à la fois le chef de projet et le développeur backend. Il ne s'agit pas seulement de tests — il s'agit d'un langage commun pour l'équipe.
\n\nD'ailleurs, si vous débutez tout juste avec TypeScript, je vous recommande de jeter un œil à la base de connaissances PythonLib — vous y trouverez d'excellents documents sur les bases. Nous, nous allons plus loin.
\n\nQu'est-ce que le BDD et pourquoi en avez-vous besoin ?
\n\nBehaviour-Driven Development est une évolution du TDD (Test-Driven Development). Si le TDD se concentre sur le « comment » fonctionne le code (les tests sont écrits avant l'implémentation), le BDD répond à la question « quoi » le système doit faire du point de vue de l'utilisateur.
\n\nLa principale caractéristique du BDD est la syntaxe Gherkin. Il s'agit de la structure « Étant donné — Quand — Alors » (Given — When — Then), qui ressemble à ceci :
\n\nFonctionnalité : Authentification utilisateur\n En tant qu'utilisateur enregistré\n Je veux me connecter au système\n Afin d'accéder à mon espace personnel\n\n Scénario : Connexion réussie\n Étant donné un utilisateur avec l'email "test@example.com" et le mot de passe "123456"\n Quand l'utilisateur saisit des données correctes\n Alors le système le redirige vers son espace personnel\n\n\nVous en conviendrez, c'est plus compréhensible que « le test unitaire vérifie que la méthode login() renvoie true » ? C'est là toute la force du BDD : les tests en TypeScript deviennent une documentation que tout membre de l'équipe peut lire.
\n\nQuand le BDD est-il rentable ?
\n\n- \n
- Logique métier complexe — lorsque le code contient de nombreuses conditions, chaînes d'actions et scénarios d'erreur. \n
- Équipes réparties — analystes à Moscou, développeurs à Minsk, testeurs à Novossibirsk. Le BDD est leur langage commun. \n
- Microservices — lorsqu'il est nécessaire de décrire clairement les contrats d'interaction entre les services. \n
Outils pour le BDD en TypeScript
\n\nPour implémenter le BDD en TypeScript, nous avons deux outils principaux : Cucumber.js (ou ses variantes) et Jest avec des plugins. Examinons les deux approches.
\n\nCucumber.js + TypeScript : le classique du genre
\n\nCucumber est le standard de référence du BDD. Il lit les fichiers Gherkin (généralement avec l'extension .feature) et exécute le code des steps que vous écrivez en TypeScript.
Installation :
\n\nnpm install --save-dev @cucumber/cucumber typescript ts-node\nnpm install --save-dev @types/node\n\n\nCréons le fichier features/login.feature :
Fonctionnalité : Connexion au système\n En tant qu'utilisateur\n Je veux m'authentifier\n Afin d'accéder aux fonctionnalités\n\n Scénario : Connexion réussie avec email et mot de passe corrects\n Étant donné que j'ouvre la page de connexion\n Quand je saisis l'email "admin@test.com"\n Et que je saisis le mot de passe "secret"\n Et que je clique sur le bouton "Connexion"\n Alors je vois le message de bienvenue "Bienvenue, Admin !"\n\n\nÉcrivons maintenant les steps en TypeScript. Créons features/step_definitions/login.steps.ts :
import { Given, When, Then } from '@cucumber/cucumber';\nimport { expect } from 'chai';\n\n// Simulation simple de l'état de l'application\nconst appState = {\n currentPage: '',\n loggedInUser: ''\n};\n\nGiven('que j\'ouvre la page de connexion', function () {\n appState.currentPage = 'login';\n appState.loggedInUser = '';\n});\n\nWhen('je saisis l\\'email {string}', function (email