# Un audit de 300 tests hérités : combien testaient vraiment quelque chose ?

> Retour d'expérience sur l'analyse d'une suite ancienne, pour distinguer les tests qui protègent réellement le code de ceux qui ne font que passer sans assertion réelle.

- Auteur : Clément Hadrot
- Publié le : 2026-09-12
- Mis à jour le : 2026-09-12
- Catégorie : Tests
- URL : https://wpmoderne.dev.wordpress-developpement.fr/tests/audit-300-tests-herites-combien-utiles/

## L’essentiel

- Un test vert ne signifie pas un test utile
- Trois familles de tests creux reviennent systématiquement
- L'audit doit déboucher sur des suppressions assumées, pas seulement des ajouts

Un client nous a confié la maintenance d'une extension de gestion documentaire vieille de six ans, dotée d'une suite de 300 tests PHPUnit affichée fièrement dans sa documentation comme preuve de qualité. Avant d'accepter d'en garantir la stabilité, nous avons mené un audit complet de cette suite, pas pour en ajouter davantage, mais pour comprendre ce qu'elle protégeait réellement. Le résultat a surpris le client autant que nous : 47 de ces 300 tests, soit environ un sur six, ne vérifiaient en réalité rien de significatif, tout en s'affichant verts à chaque exécution.

## Méthode : ne pas se fier au vert, injecter des bugs volontairement

Plutôt que de lire les 300 tests un par un, ce qui aurait pris des semaines, nous avons utilisé une approche de mutation testing ciblée avec [Infection](https://infection.github.io/) : introduire volontairement de petites altérations dans le code (inverser une condition, changer un opérateur de comparaison, supprimer une ligne) et vérifier si au moins un test échouait en réaction. Un test qui reste vert malgré une mutation qu'il est censé couvrir ne protège rien, quelle que soit son apparence dans le rapport de couverture classique.

```
vendor/bin/infection --min-msi=70 --threads=4
```

## Première famille de tests creux : l'assertion trop faible

> L'essentiel à retenir : Un test vert ne signifie pas un test utile ; Trois familles de tests creux reviennent systématiquement ; L'audit doit déboucher sur des suppressions assumées, pas seulement des ajouts

Le cas le plus fréquent, retrouvé sur 22 des 47 tests problématiques, était une assertion qui vérifie l'absence d'erreur plutôt que le résultat attendu :

```
public function test_extraction_metadonnees_document() {
    $resultat = extraire_metadonnees( $this->chemin_document_test );
    $this->assertNotNull( $resultat ); // passe même si $resultat est un tableau vide erroné
}
```

Corrigé en vérifiant le contenu réellement attendu :

```
public function test_extraction_metadonnees_document() {
    $resultat = extraire_metadonnees( $this->chemin_document_test );
    $this->assertSame( 'Rapport annuel 2019', $resultat['titre'] );
    $this->assertSame( 12, $resultat['nombre_pages'] );
}
```

## Deuxième famille : le test qui ne teste jamais la branche visée

Douze tests portaient un nom évocateur d'un cas d'erreur (`test_document_corrompu_est_rejete`) mais fournissaient en réalité, par erreur de préparation des données de test, un document parfaitement valide. Le test passait, mais parce que le code suivait le chemin nominal, jamais la branche de gestion d'erreur qu'il prétendait couvrir. La mutation qui supprimait entièrement la gestion d'erreur correspondante ne faisait échouer aucun test, révélant l'absence réelle de couverture.

## Troisième famille : le test dupliqué qui donne une fausse impression de robustesse

Treize tests, répartis sur trois fichiers différents, vérifiaient en réalité exactement le même comportement avec des données légèrement différentes en apparence, sans jamais couvrir de cas réellement distinct. Le rapport de couverture de code affichait une ligne « couverte », mais uniquement par répétition d'un seul et même scénario, sans apporter de garantie supplémentaire.

## Ce que l'audit a produit concrètement

| Catégorie | Nombre de tests concernés | Action décidée |
| --- | --- | --- |
| Assertion trop faible | 22 | Réécrits avec une assertion précise sur le résultat |
| Branche non atteinte réellement | 12 | Données de test corrigées pour couvrir le cas visé |
| Duplication sans valeur ajoutée | 13 | Fusionnés en un seul test paramétré, le reste supprimé |

## La décision la plus difficile : assumer des suppressions

> Un test supprimé fait toujours moins bien sur un graphique de « nombre de tests » qu'un test ajouté. C'est pourtant souvent la décision la plus honnête, quand ce test ne protégeait rien de réel et donnait uniquement une fausse impression de sécurité à l'équipe et au client.

Le client, initialement inquiet de voir le nombre de tests baisser de 300 à 287 après fusion des doublons, a changé d'avis en voyant le score de mutation passer de 61 % à 84 % sur le même périmètre, une mesure bien plus représentative de la protection réelle apportée par la suite.

## Pour aller plus loin

Ce retour d'expérience ne traite pas de l'audit spécifique des tests générés par une intelligence artificielle, un cas de figure distinct déjà couvert par ailleurs, avec ses propres symptômes caractéristiques. Il porte sur un problème plus ancien et plus général : une suite de tests écrite au fil de six années par des développeurs différents, sous pression de délais variables, accumule presque inévitablement ce genre de zones mortes, que seul un audit ciblé par mutation testing permet de révéler efficacement plutôt qu'une simple lecture de couverture de code.
