Publié le , Aurélien Vandaële

Faire écrire les tests avant le code par un agent IA : ma méthode avec Claude Code

Dans ma chaîne, un premier agent écrit les tests et prouve qu'ils échouent, un deuxième écrit le code pour les faire passer, un troisième relit sans avoir rien vu de l'écriture. Les tests écrits d'abord servent de contrat : l'agent qui code ne peut plus décider seul que « ça marche ».

Le problème quand un agent code puis teste

Demandez à un agent d'écrire une fonction, puis ses tests. Les tests passeront presque toujours, et c'est justement le souci : ils décrivent ce que le code fait, pas ce qu'il devait faire. Un bug de compréhension se retrouve gravé deux fois, une fois dans le code et une fois dans le test qui le valide.

Inverser l'ordre casse cette boucle. Le test est écrit à partir de la demande, avant qu'une seule ligne de code existe. Il échoue, ce qui prouve qu'il vérifie bien quelque chose. Ensuite seulement on écrit le code.

Trois rôles, jamais dans la même tête

Dans Claude Code, un sous-agent est un fichier Markdown rangé dans .claude/agents/ : une description, les outils auxquels il a droit, et ses consignes. Chaque sous-agent démarre avec un contexte neuf. C'est ce qui rend la séparation des rôles possible.

  • L'agent tests reçoit le brief d'une tâche. Il écrit les tests, les lance, montre qu'ils échouent pour la bonne raison, et s'arrête là. Il n'a pas le droit d'écrire le code.
  • L'agent code reçoit ces tests et les fait passer. Il n'a pas le droit d'affaiblir un test pour y arriver. Tests et code partent dans un seul commit.
  • L'agent relecteur ne peut que lire. Il reçoit le diff et le brief, jamais la conversation qui a produit le code. Il rend un verdict : ce qui bloque, ce qui mériterait d'être corrigé.

Le relecteur est la pièce la plus importante. Un agent qui relit son propre travail le trouve convaincant, parce qu'il se souvient de pourquoi il l'a écrit ainsi. Un agent qui n'a que le résultat sous les yeux pose les questions qu'un collègue poserait.

Les garde-fous qui tiennent la chaîne

  • Deux tours de correction, pas plus. Si le relecteur bloque encore après deux allers-retours, la chaîne s'arrête et c'est moi qui reprends. Au-delà, les agents tournent en rond.
  • Les mêmes vérifications à chaque commit : lint, typage, tests. Rien n'avance tant que tout n'est pas vert.
  • Des hooks qui interdisent les raccourcis : impossible de sauter les tests, pas de --no-verify, et une session ne peut pas se terminer en rouge.

Ces règles ne reposent pas sur la bonne volonté du modèle. Elles sont exécutées par l'outil, donc elles s'appliquent aussi les jours où le modèle est pressé d'en finir.

À quoi ressemble une session

J'ai empaqueté cette chaîne dans un plugin Claude Code que j'utilise sur tous mes projets. Une fois le plan écrit, une commande suffit :

/pipeline:init          # une fois par projet
/pipeline:build plan.md # exécute le plan, tâche par tâche

Pour chaque tâche du plan, la commande enchaîne les trois agents, lance les vérifications, et passe à la suivante. Je relis le résultat à la fin, et je suis prévenu avant si une tâche a épuisé ses deux tours.

Vous pouvez monter la même chose sans plugin : trois fichiers dans .claude/agents/, un relecteur limité aux outils de lecture, et une commande unique qui lance lint, typage et tests.

Ce que ça a changé en production

J'ai construit cette chaîne chez Bayard, sur l'application La Croix, à partir de ce que l'équipe faisait déjà avant l'IA : tests unitaires, tests de bout en bout, comparaison visuelle, analyse statique. Résultat mesuré : trois fois plus de tickets livrés et 40 % d'erreurs en moins en production.

Le gain ne vient pas d'un modèle plus malin. Il vient du fait que chaque étape est vérifiée par quelque chose d'autre que celui qui l'a faite.

Article rédigé avec l'aide de l'IA à partir de ma pratique quotidienne et de mes projets.

Tout le carnet