BDD — Behavior-Driven Development¶
Spécifications executables, langage Gherkin et living documentation — rendre les tests lisibles par tous.
Le principe¶
BDD est ne d'un constat : les tests unitaires du TDD sont écrits par des développeurs, pour des développeurs. Le Product Owner, le QA et les utilisateurs ne les lisent pas.
BDD propose d'écrire les tests dans un langage naturel structure que tout le monde comprend — puis de les rendre executables.
graph LR
A["User Story"] --> B["Scenarios Gherkin<br/>(PO + Dev + QA)"]
B --> C["Steps implementation<br/>(Dev)"]
C --> D["Execution automatisee"]
D --> E["Living Documentation"] Le langage Gherkin¶
Gherkin est un format structure en langage naturel. Chaque scenario suit le pattern Given/When/Then :
Feature: Connexion utilisateur
En tant qu'utilisateur enregistre
Je veux me connecter a mon compte
Afin d'acceder a mes donnees personnelles
Scenario: Connexion reussie avec des identifiants valides
Given un utilisateur "alice" avec le mot de passe "P@ssw0rd!"
And le compte est actif
When l'utilisateur se connecte avec "alice" et "P@ssw0rd!"
Then la connexion est reussie
And l'utilisateur est redirige vers le tableau de bord
Scenario: Connexion echouee avec un mot de passe incorrect
Given un utilisateur "alice" avec le mot de passe "P@ssw0rd!"
When l'utilisateur se connecte avec "alice" et "mauvais_mdp"
Then la connexion echoue
And le message "Identifiants invalides" est affiche
Mots-clés Gherkin¶
| Mot-clé | Rôle |
|---|---|
| Feature | Titre de la fonctionnalité |
| Scenario | Un cas de test spécifique |
| Given | Le contexte initial (preconditions) |
| When | L'action qui déclenche le comportement |
| Then | Le résultat attendu |
| And / But | Continuation du mot-clé précédent |
| Scenario Outline | Scenario parametre avec des exemples |
| Examples | Tableau de données pour un Scenario Outline |
Scenario Outline — tests parametres¶
Scenario Outline: Validation du format email
When l'utilisateur saisit l'email "<email>"
Then la validation retourne <resultat>
Examples:
| email | resultat |
| user@example.com | valide |
| user@ | invalide |
| @example.com | invalide |
| user.example.com | invalide |
La conversation structurée¶
BDD n'est pas juste un format de test — c'est un processus de découverte. Avant d'écrire les scenarios, l'équipe se reunit pour un "Three Amigos" :
graph TD
PO["Product Owner<br/>Definit le besoin"] --- SC["Scenarios<br/>Gherkin"]
DEV["Developpeur<br/>Identifie les cas limites"] --- SC
QA["QA<br/>Challenge les hypotheses"] --- SC Le processus¶
- Le PO présente la user story
- Le développeur pose des questions techniques ("que se passe-t-il si le serveur est down ?")
- Le QA cherche les cas limites ("et si l'email contient des caractères unicode ?")
- Ensemble, ils redigent les scenarios Gherkin
- Le développeur implémenté les steps
- La CI exécuté les scenarios à chaque push
L'atelier est la vraie valeur
Le format Gherkin est secondaire. La vraie valeur du BDD est la conversation qui force PO, dev et QA a s'aligner sur le comportement attendu avant le développement.
Implémentation des steps¶
Les scenarios Gherkin sont liés à du code via des step définitions :
Python (Behave)¶
# features/steps/login_steps.py
from behave import given, when, then
@given('un utilisateur "{username}" avec le mot de passe "{password}"')
def step_create_user(context, username, password):
context.user = create_user(username, password)
@when('l\'utilisateur se connecte avec "{username}" et "{password}"')
def step_login(context, username, password):
context.response = login(username, password)
@then('la connexion est reussie')
def step_login_success(context):
assert context.response.status == "success"
JavaScript (Cucumber.js)¶
// features/step_definitions/login_steps.js
const { Given, When, Then } = require('@cucumber/cucumber');
Given('un utilisateur {string} avec le mot de passe {string}', function (username, password) {
this.user = createUser(username, password);
});
When('l\'utilisateur se connecte avec {string} et {string}', function (username, password) {
this.response = login(username, password);
});
Then('la connexion est reussie', function () {
assert.strictEqual(this.response.status, 'success');
});
Living Documentation¶
Les scenarios BDD forment une documentation vivante : si un scenario passe, la fonctionnalité fonctionne comme décrit. Si un scenario échoué, la documentation est obsolète.
| Documentation classique | Living Documentation (BDD) |
|---|---|
| Devient obsolète en quelques mois | Toujours à jour (exécutée par la CI) |
| Redige une fois, jamais mis à jour | Mis à jour à chaque changement de comportement |
| Disconnect entre doc et code | La doc est le test |
Générer un rapport¶
La plupart des frameworks BDD génèrent des rapports HTML à partir des scenarios :
# Behave (Python)
behave --format html --outfile report.html
# Cucumber.js
npx cucumber-js --format html:report.html
BDD vs TDD¶
| Critère | TDD | BDD |
|---|---|---|
| Audience | Développeurs | PO, Dev, QA — toute l'équipe |
| Langage | Code | Gherkin (langage naturel) |
| Granularité | Unitaire | Fonctionnel (user story) |
| Objectif | Design du code | Alignement sur le comportement |
| Complementaire | Oui — BDD au niveau feature, TDD au niveau unitaire | Oui |
BDD ne remplacé pas TDD
BDD décrit le quoi (le comportement attendu). TDD guide le comment (la conception du code). Ils se combinent naturellement : BDD pour les scenarios d'acceptation, TDD pour l'implémentation des composants internes.
Outils¶
| Outil | Langage | Lien |
|---|---|---|
| Cucumber | Multi (JVM, JS, Ruby) | cucumber.io |
| Behave | Python | behave.readthedocs.io |
| pytest-bdd | Python | github.com/pytest-dev/pytest-bdd |
| SpecFlow | .NET | specflow.org |
| Karate | JVM | github.com/karatelabs/karate |