SECTEUR · LA POSTURE · WILLIAM LEEMANS
Les tests comme contrat
Lecture ~7 min
EN CHANTIER Cette section est en cours d’écriture : ce texte est lisible mais pas encore finalisé, son contenu peut évoluer.
L’Étape précédente s’achevait sur une consigne : laisser types, tests et exécution filtrer avant vos yeux, parce que votre attention fatigue et pas la leur.
Quand un agent écrit le code, le test change de statut. Il n’est plus le filet de sécurité qu’on écrit après coup : c’est la part de la spécification qui s’exécute, le contrat qui fixe ce qui doit être vrai pendant que la machine se charge du comment.
Et comme pour tout contrat, la question qui compte n’est pas s’il est signé. C’est qui l’a rédigé, et qui l’a relu.
Pourquoi le test change de statut ?
Parce qu’il devient le seul instrument qui convertit une déclaration en verdict.
« C’est corrigé. » « Tous les cas limites sont gérés. » « Les tests passent. » Un agent produit ces phrases comme il produit son code, et pour exactement la même raison : ce sont des continuations vraisemblables, pas des constats. La sycophantie décrite dans Limites et hallucinations s’applique d’abord aux rapports de succès. Une affirmation de l’agent sur son propre travail a la valeur de preuve d’une affirmation de l’agent sur le vôtre : aucune.
Le test, lui, dit le comportement attendu dans une forme à la fois lisible par vous et exécutable par la machine. Son résultat est binaire, reproductible, et parfaitement insensible à la conviction de celui qui l’a produit. C’est la seule réponse qui tienne face à l’asymétrie posée à l’Étape précédente : l’agent produit plus vite que vous ne relisez, mais il ne produit pas plus vite que la suite ne s’exécute.
D’où le changement de statut. Tant qu’un humain écrivait le code, le test coûtait à peu près aussi cher que l’implémentation, et cette économie en faisait une assurance — souvent négociée, parfois sacrifiée. Quand l’implémentation ne coûte presque rien, ce qui reste rare, c’est la définition exacte de ce qu’elle doit faire.
Le test devient cette définition. La forme la plus dense et la moins ambiguë de spécification qu’un modèle puisse recevoir, et la seule qui se vérifie elle-même.
Qui doit écrire les tests ?
Vous, au moins pour l’intention. Laisser l’agent écrire l’implémentation et ses tests dans le même geste produit une circularité très confortable et complètement vide : les tests documentent ce que le code fait, pas ce qu’il devrait faire.
J’aime bien l’image de l’expert qui rédigerait lui-même le constat de son propre accident. Tout est cohérent, et ça ne prouve rien. Si la compréhension de la tâche a un angle mort, le code et les tests partagent l’angle mort, et la suite verte certifie l’erreur. Un contrat rédigé par la partie qui doit le remplir n’engage personne.
Trois niveaux d’implication, à calibrer sur le coût de l’erreur :
- Sur les chemins critiques, écrivez les tests vous-même, ou au minimum les assertions. Calcul, argent, droits d’accès, migration : c’est ici que votre expertise se condense en quelques lignes exécutables, et c’est un bien meilleur usage de votre temps d’écriture que l’implémentation.
- Ailleurs, faites rédiger le brouillon par l’agent, mais relisez-le comme une spécification. Un test bien écrit est court, déclaratif, sans logique habile : le relire coûte une fraction de la relecture de l’implémentation. Si vous ne devez lire qu’une chose ligne à ligne dans un diff, lisez les tests. C’est la passe de détail de l’Étape précédente.
- Dans tous les cas, voyez le test échouer avant de déléguer. Un test que vous n’avez jamais vu rouge ne prouve rien : il peut être tautologique, mal branché, ou tester un comportement déjà présent. Le rouge initial est la signature du contrat.
Comment marche la boucle rouge-vert avec un agent ?
En trois temps, et c’est le seul protocole où la délégation est bornée par construction. Le TDD a toujours été défendu pour la pression de conception qu’il exerce ; avec un agent, il gagne un second argument, beaucoup plus terre à terre.
- Rédigez ou validez le test, constatez le rouge. Le contrat existe, l’écart aussi.
- Donnez la commande qui fait foi (« la tâche est finie quand
pnpm testpasse ») et laissez l’agent itérer. L’autonomie ne coûte rien ici : chaque essai est jugé par la suite, pas par sa plausibilité, et vous n’avez pas à relire les tentatives intermédiaires. - Traitez le vert comme une autorisation de relire, pas comme une absolution. Le contrat garantit les comportements qu’il énonce, rien d’autre. La passe d’intention et la passe d’intégration de l’Étape précédente restent dues.
LE CRAFTOMANCER
Un agent optimise le verdict, pas la vertu. Si le chemin le plus court vers le vert passe par l’affaiblissement du contrat (assertion assouplie, cas commenté,
skipdiscret, valeur attendue recopiée depuis la sortie obtenue), certains modèles le prendront, sans malice. Verrouillez la règle : pendant qu’il fait passer les tests, l’agent ne les modifie pas. Et tout diff qui touche à la fois aux tests et au code se relit en commençant par les tests. C’est peut-être une mise à jour légitime du contrat, mais c’est à vous d’en décider.
Comment reconnaître un test décoratif ?
En lui demandant ce qu’il promet — et en constatant qu’il ne promet rien. Parce que la défaillance signature des tests générés n’est pas le test faux : celui-là échouerait, on le verrait. C’est le test décoratif. Vert, nombreux, et muet.
Trois espèces reviennent tout le temps :
- Le test-miroir, qui paraphrase l’implémentation : tout est mocké, et l’assertion vérifie que le mock a bien été appelé avec ce que le code lui passe. Il teste le câblage, jamais le comportement. Il survivra à tous les bugs et cassera à tous les refactorings — l’exact inverse d’un contrat.
- Le chemin heureux exhaustif : douze variantes du cas nominal, zéro cas limite. L’agent teste ce qu’il a pensé à implémenter. Ce qu’il a oublié dans le code, il l’a oublié dans les tests, au même endroit.
- La couverture comme métrique de vanité. La couverture mesure ce qui s’exécute, pas ce qui est promis. Cent pour cent de lignes couvertes par des assertions creuses, c’est cent pour cent de figuration.
Le tri tient en deux questions, et je me les pose dans cet ordre. Lisez le test seul : pouvez-vous dire quel comportement il promet ? Puis pensez en mutant : si on réintroduit le bug, ou qu’on inverse cette condition, ce test hurle-t-il ?
Un test qui survivrait au bug qu’il est censé interdire n’est pas un contrat. C’est un décor, qui coûte de la maintenance sans rien garantir.
Pourquoi la suite de tests est la mémoire du projet ?
Parce que c’est la seule consigne qui ne sort jamais du contexte — pour la bonne raison qu’elle n’y vit pas.
Un agent n’a pas de mémoire : chaque session repart de zéro, et les consignes répétées dans le chat finissent par sortir de la fenêtre. La suite de tests, elle, s’exécute à chaque itération, quelle que soit la session, quel que soit le modèle.
D’où une discipline de capitalisation qui rapporte énormément : chaque bug de production, chaque diff refusé pour une raison de fond devient un test avant de devenir un correctif.
L’Étape précédente recommandait de régénérer un diff médiocre plutôt que de le rafistoler ; c’est la suite de tests qui rend ce geste bon marché. Régénérer sans contrat, c’est rejouer aux dés. Régénérer sous contrat, c’est réessayer sans risque. Et un test rouge reste le meilleur rapport de bug qu’un agent puisse recevoir : reproductible, sans ambiguïté, auto-vérifiant.
En pratique
- Aucune déclaration de succès ne vaut verdict : ce que l’agent affirme, un test doit pouvoir le prononcer.
- Avant de déléguer une tâche non triviale, fixez le contrat : des tests écrits ou validés par vous, vus rouges au moins une fois.
- Donnez la commande qui fait foi et laissez l’agent itérer jusqu’au vert. Le vert autorise la relecture, il ne la remplace jamais.
- Pendant la mise en conformité, l’agent ne touche pas aux tests. Tout diff qui modifie code et tests à la fois se relit en commençant par les tests.
- Traquez le décoratif : un test dont vous ne savez pas dire ce qu’il promet, ou qui survivrait au bug réintroduit, se supprime ou se réécrit.
- Capitalisez : chaque bug, chaque refus motivé devient un test. La suite est la mémoire exécutable du projet.
Le contrat garantit que le code tient ses promesses ; il ne dit pas encore ce que contient le colis. Dépendances embarquées, surface exposée, chemins jamais exécutés : c’est l’objet de la prochaine Étape de la Section, comprendre ce qu’on livre.