Test After, Test First, TDD : ce que chaque approche garantit vraiment
“On fait du TDD” — vraiment ?
Dans beaucoup d’équipes, “on fait du TDD” signifie en réalité : on écrit des tests. Après avoir codé. En espérant couvrir les cas importants.
C’est du Test After. Ce n’est pas du TDD. Et la différence n’est pas qu’une question de timing — elle détermine ce que les tests peuvent détecter.
Les trois approches
Test After — la réalité de beaucoup d’équipes
On écrit le code d’abord. On ajoute les tests ensuite.
Ce que ça garantit : que le code testé se comporte comme on l’a écrit. C’est-à-dire : les tests capturent l’état actuel du code, bugs compris.
Le problème central : le biais de confirmation. Quand on a écrit le code, on écrit les tests pour qu’ils passent. On ne cherche pas à trouver des bugs — on cherche à valider ce qu’on a fait. Résultat : les cas limites sont systématiquement sous-testés.
Sa vraie valeur : la non-régression. Les tests écrits après coup ont peu de valeur pour détecter des bugs présents, mais beaucoup pour détecter des régressions futures.
Test First — l’architecture déjà connue
On écrit le test avant d’écrire le code.
Ce que ça garantit : que le code est conçu pour être testable, et que les comportements attendus sont explicités avant l’implémentation.
Sa limite : il faut déjà savoir comment le code va être structuré. On écrit un test pour UserRepository.FindByEmail, ce qui suppose qu’on a décidé qu’il y aura un UserRepository avec une méthode FindByEmail. C’est difficile quand on explore un nouveau domaine.
Cas typique : développement avec des specs complètes et une architecture établie. On sait ce qu’on va construire, on formalise d’abord le contrat.
TDD — le test comme outil de conception
On n’écrit pas juste le test avant le code. Le test guide l’écriture du code. Le cycle est : Red → Green → Refactor.
Red : écrire un test qui échoue (il n'y a pas encore de code)
Green : écrire le minimum de code pour faire passer le test
Refactor : améliorer le code sans changer le comportement (les tests protègent)
Ce que ça garantit : que chaque ligne de code existe pour satisfaire un besoin exprimé par un test. Que l’architecture émerge des contraintes de testabilité. Que le refactoring est sécurisé dès le premier jour.
Sa vraie force : le cycle Red/Green/Refactor force à penser en termes de comportements attendus, pas d’implémentations. Résultat : une architecture plus découplée, des interfaces mieux définies, et des tests qui testent des comportements — pas des méthodes.
Ce que chaque approche détecte
| Situation | Test After | Test First | TDD |
|---|---|---|---|
| Régressions futures | ✅ | ✅ | ✅ |
| Bugs dans le code existant | ❌ (biais) | ✅ | ✅ |
| Mauvaise conception | ❌ | Partiel | ✅ |
| Code non testable | ❌ | ✅ | ✅ |
| Cas limites oubliés | ❌ | Partiel | ✅ |
Comment choisir ?
TDD est l’approche la plus complète, surtout pour la logique métier nouvelle. Elle est difficile à adopter d’un coup sur une équipe entière, mais elle s’apprend progressivement.
Test First est légitime quand l’architecture est établie et les specs précises. On gagne la réflexion préalable sans la rigueur du cycle complet.
Test After reste valable pour le code utilitaire simple, les scripts one-shot, ou les régions de code très stables. Ce n’est pas une erreur — c’est un choix conscient avec des contraintes connues.
Le vrai problème, c’est de faire du Test After en croyant faire du TDD.
En résumé
- Test After : capte les régressions, pas les bugs. Souffre du biais de confirmation.
- Test First : force à penser le contrat avant l’implémentation. Nécessite une architecture connue.
- TDD : les tests guident la conception. Meilleure détection des bugs et meilleure architecture — au prix d’un investissement initial.
La question n’est pas “est-ce que je dois faire du TDD ?” mais “est-ce que je sais ce que mon approche actuelle garantit — et ne garantit pas ?”
Le cycle TDD, les principes FIRST et les bonnes pratiques de tests sont au programme de mes formations Tests & Validation au CNAM Strasbourg.