TDD avec un agent
Red-green-refactor piloté par un agent : le test comme spécification exécutable, la boucle fermée comme garantie. Quand le test parle, l'agent écoute — et corrige.
Le test comme spécification exécutable pour l’agent
En développement classique, le TDD (Test-Driven Development) consiste à écrire le test avant le code. Avec un agent, cette pratique prend une dimension supplémentaire : le test devient la spécification que l’agent peut vérifier lui-même. Là où un prompt textuel reste ambigu (« implémente un service de calcul de remise »), un test est binaire : il passe ou il échoue.
Pourquoi le test est le meilleur prompt
Un test xUnit bien écrit contient trois informations que l’agent peut exploiter sans interprétation :
- Le comportement attendu : le nom du test décrit le scénario.
- Les entrées : les paramètres passés dans le Arrange/Act.
- La sortie attendue : l’assertion dans le Assert.
Point clé : Un test est un prompt non ambigu. L’agent n’a pas besoin d’interpréter ce que tu veux : il lui suffit de faire passer le test.
Red-green-refactor avec un agent
Le cycle TDD classique — red (test échoue), green (code minimal pour passer), refactor (améliorer sans casser) — devient une boucle agentique fermée quand l’agent exécute les tests lui-même.
La boucle en pratique
- Red : tu écris (ou l’agent écrit) un test qui échoue. L’échec confirme que le test teste bien quelque chose.
- Green : l’agent implémente le code minimal pour faire passer le test. Il exécute
dotnet test, voit le résultat. - Refactor : l’agent restructure le code sans casser les tests. Il relance
dotnet testpour confirmer.
La différence avec le TDD humain : l’agent peut itérer cette boucle automatiquement. Si le test échoue après l’implémentation, il lit le message d’erreur, corrige, et relance — sans intervention humaine.
Point clé : Le cycle red-green-refactor transforme le développement agentique en boucle fermée : l’agent observe (test rouge), agit (implémente), vérifie (test vert), et améliore (refactor). C’est la boucle agentique appliquée au code.
LP7 Tests : le meilleur point de levier
Dans le cadre des 12 Leverage Points appliqués au développement agentique, les tests automatisés occupent la position LP7. C’est le meilleur mécanisme de feedback qu’un agent puisse avoir : immédiat, binaire, reproductible.
Pourquoi les tests surpassent les autres feedbacks
- Compilation : dit « ça compile » mais pas « ça fait ce qu’on veut ».
- Linting : vérifie le style, pas le comportement.
- Review humaine : pertinente mais lente, non automatisable dans la boucle.
- Tests : vérifient le comportement, sont automatisables, donnent un feedback en secondes.
Point clé : Les tests sont le seul feedback qui ferme la boucle comportementale. L’agent ne vérifie pas qu’il a écrit du code valide — il vérifie qu’il a produit le comportement demandé.
Attention : Un build qui passe sans tests est un faux positif. L’agent croit avoir terminé alors qu’il n’a vérifié que la syntaxe. Sans tests, la boucle agentique est ouverte — l’agent ne sait pas si son code fait ce qu’on attend.
Closed-loop TDD : le workflow complet
Le Closed-Loop Prompting appliqué au TDD produit un prompt structuré qui inclut la vérification et la correction :
Implémente la méthode CalculateDiscount dans DiscountService.
Puis exécute dotnet test.
Si des tests échouent, lis les messages d'erreur, corrige, et relance.
Répète jusqu'à ce que tous les tests passent.
Ce prompt transforme une instruction simple en boucle fermée. L’agent ne s’arrête pas à la première tentative : il itère jusqu’à convergence.
Les quatre étapes du closed-loop TDD
- 1. Écrire le test : le humain ou l’agent rédige le test à partir de la spec.
- 2. Implémenter : l’agent écrit le code de production.
- 3. Vérifier : l’agent exécute
dotnet testet lit le résultat. - 4. Corriger ou terminer : si rouge, l’agent corrige et retourne à l’étape 3. Si vert, il passe au refactor ou au test suivant.
Point clé : Le closed-loop TDD rend l’agent autonome sur le cycle d’implémentation. Le humain intervient sur le quoi (spec, tests), l’agent gère le comment (implémentation, correction, itération).
Qui écrit le test ? Patterns pratiques
Humain écrit les tests, agent implémente
Le pattern le plus sûr. Le humain contrôle le quoi (les tests définissent le comportement) et l’agent gère le comment (l’implémentation). En architecture hexagonale .NET, cela signifie : le humain écrit les tests du domaine (comportement métier), l’agent implémente les agrégats, value objects et domain services.
Agent écrit les tests et le code
Plus risqué : l’agent peut écrire des tests qui correspondent à son implémentation plutôt qu’au besoin réel. Ce pattern nécessite une review humaine des tests avant l’implémentation.
Qualité des assertions
Un test utile pour un agent doit avoir des assertions précises et comportementales. En .NET avec FluentAssertions :
result.Should().Be(expected)— assertion précise sur la valeur.result.Should().NotBeNull()— trop faible, passe même si le résultat est faux.action.Should().Throw<DomainException>()— vérifie le comportement d’erreur.
Attention : Un test avec une assertion trop faible (
Assert.NotNullsur un objet qui ne devrait jamais être null) est un faux ami : il passe toujours, ne guide pas l’agent, et donne une fausse confiance.
TDD en .NET avec un agent : xUnit et architecture hexagonale
L’architecture hexagonale (ports et adapters) rend le TDD agentique particulièrement efficace : le domaine est isolé des dépendances externes, donc testable sans infrastructure.
Tester le domaine sans infrastructure
En hexagonal, les tests du domaine n’ont besoin ni de base de données, ni de serveur HTTP. L’agent peut exécuter dotnet test --filter Category=Domain en quelques secondes et obtenir un feedback immédiat sur la logique métier.
Granularité des tests
- Tests unitaires du domaine : rapides, isolés, idéaux pour la boucle red-green-refactor agentique.
- Tests d’intégration : vérifient les adapters (repository, API). Plus lents, utiles en fin de cycle.
- Tests de bout en bout : vérifient la chaîne complète. Trop lents pour la boucle agentique rapide.
Point clé : Pour le TDD agentique, privilégie les tests unitaires du domaine : rapides (feedback en secondes), isolés (pas de dépendance externe), et comportementaux (vérifient la logique métier, pas l’infrastructure).
Anti-patterns du TDD agentique
| Anti-pattern | Symptôme | Correction |
|---|---|---|
| Test fantôme | Le test passe mais ne vérifie rien d’utile | Chaque test doit pouvoir échouer si le comportement change |
| Test couplé à l’implémentation | Le test vérifie les appels internes au lieu du résultat | Tester le comportement observable, pas la mécanique interne |
| Tests écrits après le code par l’agent | Les tests sont taillés pour passer, pas pour spécifier | Écrire (ou valider) les tests avant l’implémentation |
| Boucle infinie de correction | L’agent corrige un test, en casse un autre | Fixer un nombre maximal d’itérations et remonter à l’humain |
| Tests trop lents dans la boucle | L’agent attend 2 minutes par itération | Séparer tests rapides (domaine) et lents (intégration) |
Attention : L’anti-pattern le plus dangereux est le test qui passe sans rien tester. L’agent le voit vert, conclut qu’il a terminé, et passe à la suite. Le bug se révèle en production, pas dans la boucle agentique.