# Tests de caractérisation contre tests de régression : la nuance qui compte

> Deux familles de tests qu'on confond souvent, alors qu'elles ne répondent pas à la même question ni au même moment du projet.

- Auteur : Clément Hadrot
- Publié le : 2023-10-08
- Mis à jour le : 2023-10-08
- Catégorie : Tests
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tests/tests-caracterisation-vs-regression-nuance/

## L’essentiel

- Figer un comportement existant, même imparfait
- Verrouiller un bug corrigé pour de bon
- Deux outils, deux moments différents du projet

Un client nous a confié un plugin de réservation vieux de sept ans, sans un seul test, avec une fonction `calculer_disponibilite()` de deux cents lignes que personne dans l'équipe n'osait toucher. La première réaction d'un développeur pressé est d'écrire des tests « comme d'habitude » : on décrit ce que la fonction devrait faire, on lance, ça casse partout, et on perd une journée à se demander si le bug est dans le code ou dans le test.

C'est là que la distinction entre test de caractérisation et test de régression prend tout son sens. Ce ne sont pas deux synonymes d'un même réflexe de prudence : l'un sert à comprendre, l'autre sert à protéger. Les confondre mène soit à des tests qui figent des bugs comme s'ils étaient des fonctionnalités, soit à une suite de régression qui ne dit jamais pourquoi le code se comporte ainsi.

## Le test de caractérisation : photographier l'existant

Un test de caractérisation ne vérifie pas qu'un comportement est correct. Il enregistre ce que le code fait *réellement*, aujourd'hui, avec les entrées qu'on lui donne. On l'écrit en appelant la fonction avec un jeu de données représentatif, en notant la sortie obtenue (même si elle semble étrange), puis en transformant cette observation en assertion.

Concrètement, sur `calculer_disponibilite()`, on a commencé par des appels bruts sans aucune assertion, juste pour observer :

```
$resultat = calculer_disponibilite( $chambre_id, '2023-10-08', '2023-10-12' );
var_dump( $resultat );
// bool(false) — inattendu, mais c'est le comportement actuel
```

Une fois ce comportement constaté, on le fige dans une assertion, quitte à ce qu'elle documente un défaut :

```
public function test_disponibilite_periode_chevauchante_retourne_false() {
    $resultat = calculer_disponibilite( $this->chambre_id, '2023-10-08', '2023-10-12' );
    $this->assertFalse( $resultat ); // comportement actuel, pas forcément désiré
}
```

## Le test de régression : garder la promesse d'un correctif

Le test de régression naît d'un bug corrigé. Son objectif est inverse : il encode le comportement *attendu*, celui qui doit rester vrai indéfiniment. On l'écrit après avoir compris la cause du problème, en général à partir d'un ticket qui décrit un cas précis observé en production.

> L'essentiel à retenir : Figer un comportement existant, même imparfait ; Verrouiller un bug corrigé pour de bon ; Deux outils, deux moments différents du projet

Reprenons l'exemple : une fois qu'on a compris que `calculer_disponibilite()` retournait `false` à tort sur les périodes chevauchant minuit, on corrige la fonction, puis on écrit :

```
public function test_disponibilite_ne_bloque_plus_a_minuit() {
    $resultat = calculer_disponibilite( $this->chambre_id, '2023-10-08 23:00', '2023-10-09 01:00' );
    $this->assertTrue( $resultat );
}
```

Ce test n'a aucune vocation exploratoire : il protège une décision de conception. S'il échoue un jour, c'est qu'une régression vient de se produire, point final.

## Pourquoi l'ordre des opérations compte

Sur du code hérité, l'erreur classique consiste à vouloir écrire directement des tests de régression avant d'avoir caractérisé quoi que ce soit. On se retrouve à deviner le comportement voulu sans filet, ce qui est exactement le problème qu'on cherche à résoudre. La caractérisation vient toujours en premier : elle donne un socle stable sur lequel refactorer sans peur, puis les tests de régression viennent documenter chaque correction ultérieure.

- Caractérisation : on observe, on enregistre, on ne juge pas.
- Refactoring : on s'appuie sur les tests de caractérisation comme filet de sécurité.
- Correction de bug : on comprend la cause, on corrige, puis on ajoute un test de régression ciblé.
- Nettoyage : certains tests de caractérisation qui documentaient un vrai bug sont remplacés par des tests de régression une fois le défaut corrigé.

## Un piège fréquent : la caractérisation qui devient permanente

Sur le projet de réservation, deux tests de caractérisation sont restés six mois dans la suite alors qu'ils décrivaient un bug connu. Un nouveau développeur, ne connaissant pas l'historique, a lu ces tests comme une spécification et a construit une fonctionnalité dessus. Résultat : corriger le bug plus tard est devenu plus coûteux, puisqu'il fallait aussi défaire ce qui en dépendait.

> Un test de caractérisation qui traîne plus de quelques semaines mérite un commentaire explicite du type `// TODO: comportement à corriger, voir ticket #482`, sinon il finit par être pris pour argent comptant.

## En résumé

Le test de caractérisation répond à la question « que fait ce code aujourd'hui ? », le test de régression répond à « ce correctif doit-il tenir dans le temps ? ». Le premier sert de filet pendant l'exploration d'un code inconnu, le second scelle une décision. Confondre les deux, c'est soit sanctuariser des bugs, soit avancer sans filet sur du code qu'on ne comprend pas encore. Sur un projet hérité, mieux vaut assumer cette étape intermédiaire, même si elle ne produit à première vue que des assertions qui semblent absurdes : elles ne le sont que temporairement.
