Développement piloté par les tests (TDD)
Le TDD est le cycle rouge → vert. Cette compétence est la référence qui permet à ce cycle de produire des tests qui valent la peine d'être conservés : ce qu'est un bon test, où placer les tests, les anti-patrons et les règles du cycle. Chaque section s'applique à chaque itération : consultez-les avant et pendant le cycle, pas après.
Lors de l'exploration du codebase, lisez GLOSSARY.md (s'il existe) afin que les noms des tests et le vocabulaire des interfaces correspondent au langage du domaine du projet, et respectez les ADR dans la zone que vous touchez.
Ce qu'est un bon test
Les tests vérifient le comportement via les interfaces publiques, pas les détails d'implémentation. Le code peut changer complètement ; les tests ne devraient pas. Un bon test se lit comme une spécification : « l'utilisateur peut finaliser une commande avec un panier valide » vous indique exactement quelle capacité existe, et il survit aux refactorisations car il ne se soucie pas de la structure interne.
Consultez tests.md pour des exemples et mocking.md pour les directives de simulation.
Seams : où placer les tests
Un seam est la frontière publique à laquelle vous testez : l'interface où vous observez le comportement sans accéder à l'intérieur. Les tests se placent aux seams, jamais contre les internes.
Testez uniquement aux seams préalablement convenus. Avant d'écrire un test, notez les seams testés et confirmez-les avec l'utilisateur. Aucun test n'est écrit sur un seam non confirmé. Vous ne pouvez pas tout tester, donc convenir des seams en amont permet de concentrer l'effort de test sur les chemins critiques et la logique complexe plutôt que sur tous les cas limites.
Demandez : « Quelle est l'interface publique, et quels seams devrions-nous tester ? » Donnez à chaque seam proposé une note d'une ligne sur ce qu'il capture et ce qu'il manque.
Lorsque la forme de cette interface elle-même est remise en question (profondeur du module, emplacement du seam, ce que l'interface doit exposer), appelez l'outil Skill avec « codebase-design » pour le vocabulaire. C'est la source commune des termes module, interface, profondeur, seam, adaptateur, levier et localité, et c'est une référence à consulter, pas une session à exécuter.
Anti-patrons
- Couplé à l'implémentation : simule les collaborateurs internes, teste les méthodes privées ou vérifie via un canal secondaire (interroger la base de données au lieu d'utiliser l'interface). L'indice : le test casse lors d'une refactorisation alors que le comportement n'a pas changé.
- Tautologique : l'assertion recalcule la valeur attendue de la même manière que le code (
expect(add(a, b)).toBe(a + b), un snapshot dérivé manuellement de la même manière, une constante affirmée égale à elle-même), donc elle réussit par construction et ne peut jamais être en désaccord avec le code. Les valeurs attendues doivent provenir d'une source de vérité indépendante : un littéral connu correct, un exemple travaillé, la spécification. - Découpage horizontal : écrire tous les tests d'abord, puis toute l'implémentation. Les tests en bloc vérifient un comportement imaginé : vous testez la forme des choses plutôt que le comportement face à l'utilisateur, les tests deviennent insensibles aux changements réels, et vous vous engagez sur une structure de test avant de comprendre l'implémentation. Travaillez plutôt par tranches verticales : un test → une implémentation → répétez, chaque test étant une balle traceuse qui répond à ce que le dernier cycle vous a appris.
Règles du cycle
- Rouge avant vert. Écrivez d'abord le test qui échoue, puis seulement assez de code pour le faire passer. N'anticipez pas les tests futurs et n'ajoutez pas de fonctionnalités spéculatives.
- Une tranche à la fois. Un seam, un test, une implémentation minimale par cycle.
- La refactorisation ne fait pas partie du cycle. Elle appartient à l'étape de revue (voir la compétence
code-review), pas au cycle d'implémentation rouge → vert.