Réponse courte
Écrivez de petits tests automatisés qui décrivent le comportement voulu, lancez-les pour confirmer qu’ils échouent, validez-les dans le dépôt, puis seulement ensuite demandez à l’agent de programmation d’écrire du code jusqu’à ce que tous les tests passent, sans toucher aux fichiers de tests. Les tests deviennent une cible que l’agent peut lancer après chaque changement : il vérifie ainsi son propre travail au lieu de vous demander s’il a terminé.
Question de suivi Comment l’empêcher de modifier les tests?
Un agent de programmation est un outil d’IA, comme Claude Code ou Codex d’OpenAI, qui lit votre projet, modifie des fichiers et exécute des commandes pour accomplir une tâche de programmation. Son point faible, c’est de savoir quand il a réussi. Si on lui demande de « corriger l’analyseur de prix », il peut écrire du code plausible et crier victoire. Donnez-lui plutôt un ensemble de tests, et « terminé » devient quelque chose qu’il peut mesurer : lancer les tests, lire les échecs, changer le code, les relancer.
C’est une vieille méthode appliquée à un nouveau genre de programmeur. Le développement piloté par les tests (test-driven development, TDD), associé à l’ingénieur logiciel Kent Beck, fonctionne en une courte boucle souvent appelée rouge, vert, remaniement : écrire un test qui échoue (rouge), écrire juste assez de code pour le réussir (vert), puis remettre le code en ordre tout en gardant les tests au vert. Le guide d’Anthropic sur la programmation agentique avec Claude Code recommande exactement ce modèle pour les agents, en ajoutant une règle : l’agent doit faire passer les tests sans les modifier.
Étape 1 : décrire le comportement sous forme de tests
Supposons qu’une petite application de commerce ait besoin d’une fonction qui transforme le texte d’un prix tapé par le personnel en un nombre entier de cents. Avant qu’il existe la moindre ligne de code, écrivez ce que « correct » veut dire. Cet exemple utilise Python et pytest, un outil de test très répandu qui trouve les fonctions dont le nom commence par test_ et les exécute.
# tests/test_prices.py
import pytest
from prices import parse_price
def test_plain_dollars():
assert parse_price("$12") == 1200
def test_cents_and_thousands():
assert parse_price("$1,234.50") == 123450
def test_spaces_and_no_symbol():
assert parse_price(" 7.05 ") == 705
def test_rejects_words():
with pytest.raises(ValueError):
parse_price("twelve dollars")
def test_rejects_three_decimals():
with pytest.raises(ValueError):
parse_price("$1.005")
Chaque test est une phrase de la spécification. Les deux derniers comptent autant que les trois premiers : ils disent ce que la fonction doit refuser. C’est dans les cas limites que les agents, comme les gens, ont tendance à tourner les coins ronds.
Ajoutez une fonction provisoire pour que l’importation fonctionne :
# prices.py
def parse_price(text):
raise NotImplementedError
Étape 2 : les regarder échouer, puis les valider
Lancez les tests :
pytest -q
Les cinq devraient échouer. Cette étape n’est pas une formalité. Un test qui passe avant que le code soit écrit est défectueux, puisqu’il passerait aussi si le code était faux. Voir du rouge prouve que chaque test peut attraper une erreur.
Enregistrez maintenant les tests dans le système de gestion de versions, pour avoir un point de référence fixe :
git add tests/test_prices.py prices.py
git commit -m "Ajoute les tests qui échouent pour parse_price"
chmod a-w tests/test_prices.py # rendre le fichier de tests en lecture seule
Étape 3 : donner la cible à l’agent
Les tests dans tests/test_prices.py décrivent le comportement de parse_price dans prices.py.
Ils échouent pour l’instant. Implémente parse_price pour qu’ils passent tous.
Règles :
- Ne modifie, ne supprime, ne renomme et ne saute aucun test, et ne modifie aucun fichier dans tests/.
- Lance `pytest -q` après chaque changement et continue jusqu’à ce que tous les tests passent.
- Si tu crois qu’un test est erroné, arrête-toi et explique pourquoi au lieu de le modifier.
- Quand tu as terminé, montre-moi le code final et la dernière sortie des tests.L’agent dispose maintenant d’une boucle qu’il peut faire tourner seul : modifier, tester, lire l’erreur, modifier de nouveau. Le guide d’Anthropic note que les agents donnent leur meilleur quand ils ont une cible claire sur laquelle itérer, et une suite de tests est la plus claire qui soit. Claude Code demande aussi la permission par défaut avant de modifier des fichiers ou d’exécuter des commandes : vous pouvez donc suivre chaque étape au début.
Étape 4 : vérifier ce qu’affirme l’agent
Quand l’agent dit avoir terminé, vérifiez vous-même deux choses :
pytest -q # tous les tests passent
git diff --exit-code HEAD -- tests/ # tests inchangés depuis votre commit
La deuxième commande n’affiche rien et se termine avec succès si le dossier des tests est identique à ce que vous avez validé. Lisez ensuite le code. Des tests réussis prouvent que les cas énumérés fonctionnent; ils ne prouvent pas que le code est clair, ni qu’il gère un cas que vous avez oublié d’écrire.
À essayer : choisissez une petite fonction dont vous avez besoin, comme une fonction qui vérifie si un code postal est valide. Écrivez cinq tests, dont deux cas qui doivent être refusés, et confirmez que les cinq échouent. Validez-les, donnez à votre agent de programmation le prompt ci-dessus et lancez les deux vérifications quand il annonce sa réussite.
Comment l’empêcher de modifier les tests?
Dites-le-lui, puis assurez-vous qu’il ne peut pas vous ignorer en douce. Une consigne dans le prompt est la première couche. Répétez-la dans le fichier de projet que l’agent lit au début de chaque session, comme CLAUDE.md pour Claude Code, pour que la règle survive à une nouvelle conversation.
La deuxième couche, c’est votre configuration. Validez les tests avant que l’agent commence; toute modification apparaîtra alors dans git diff. Rendre les fichiers de tests en lecture seule, comme ci-dessus, transforme une modification désinvolte en une erreur de permission visible. Gardez actives les demandes de permission de l’agent pour la modification de fichiers, et refusez tout changement dans tests/. Anthropic prévient que sauter les vérifications de permission est risqué et ne devrait se faire que dans un conteneur isolé.
La troisième couche est une vérification automatique. Dans votre système d’intégration continue, le service qui lance des vérifications à chaque changement, ajoutez une étape qui échoue si un fichier de tests diffère de la version révisée. Quelques tests supplémentaires que l’agent ne voit jamais, gardés hors de son dossier de travail et lancés par vous seul, aident aussi : un code écrit pour coller de trop près aux tests visibles échouera souvent à ceux-là.
Enfin, gardez une porte ouverte. Il arrive qu’un test soit réellement erroné. Demander à l’agent de s’arrêter et d’expliquer, plutôt que de modifier, veut dire que c’est vous qui décidez, et les tests restent la description de ce que vous voulez.
Sources
- Claude Code: Best practices for agentic coding — Anthropic, 18 avril 2025
- Test-driven development (Wikipedia, revision of 23 March 2026) — Wikipedia, 23 mars 2026