Publié le: Juillet 6, 2026
Le Génie et le Contrat
Comment le développement piloté par les spécifications (SDD) et le développement piloté par les tests (TDD) s'articulent réellement lorsqu'un agent non déterministe écrit votre code — et où la version naïve s'effondre discrètement.

Un génie imprévisible
Kent Beck défend depuis cinquante ans l'idée que les tests doivent primer. Il est donc intéressant de s'intéresser à la manière dont il décrit les agents de programmation d'IA avec lesquels il travaille actuellement : un « génie imprévisible » qui exauce vos vœux, souvent de manière littérale et inattendue. Vous demandez quelque chose. On vous le donne. quelque choseReste à savoir si c'est ce dont vous aviez réellement besoin.
Dans la même conversation, Beck qualifie le TDD de "superpuissance" avec ces agents, car ils introduisent constamment des régressions et une suite de tests est le moyen le plus économique de les détecter. Mais il laisse également échapper un détail qui devrait vous faire réfléchir : il a du mal à empêcher les agents de… suppression des tests pour qu'ils réussissent. Les tests, à la fois rempart et outil de manipulation : voilà le problème.
Un petit mot sur la terminologie, car l'un de ces acronymes est souvent utilisé à tort. TDD est la méthode la plus ancienne : écrire d'abord un test qui échoue, écrire juste assez de code pour le faire réussir, nettoyer le code, et recommencer. SDD est la méthode plus récente : formaliser ce que vous développez dans une spécification technique structurée (structures de l'API, modèles de données et critères d'acceptation) et considérer ce document comme le contrat que le code doit respecter. L'important est que SDD soit… pratique, pas un produit. Kit de spécifications de GitHub est un outil qui facilite son adoption, et il sert d'exemple tout au long de ce document ; cependant, tout ce qui est présenté ici s'applique à toute configuration SDD. (Ce n'est pas non plus la même chose que axé sur l'histoire développement, qui fonctionne à un niveau plus souple au niveau des récits utilisateurs et se rapporte différemment au TDD.)
Pourquoi aucun des deux ne survit seul au génie
Si on exécute SDD seul, le sens se perd : l'agent interprète à sa manière une spécification ambiguë et construit un code cohérent, mais qui ne correspond toujours pas à l'intention initiale, car la prose ne peut être exécutée et rien ne ramène le code aux mots. Si on exécute TDD seul, on obtient l'inverse : un code qui réussit les tests et rien de plus, sans spécification pour définir ces tests. devrait Ils affirment donc qu'ils finissent par encoder ce que l'agent a décidé de construire. Dans les deux cas : coches vertes, cible incorrecte.
La raison de les combiner n'est pas que les deux soient agréables. C'est que La spécification et le test sont deux encodages indépendants d'une même intention. L'un est lisible par un humain, l'autre exécutable par une machine ; chacun comble les lacunes de l'autre. La spécification justifie l'existence du test, évitant ainsi que la suite ne soit qu'une simple copie du code. Le test donne du poids à la spécification, empêchant l'agent de la réinterpréter discrètement.
Un panneau de spécifications à gauche et un panneau de test à droite pointent tous deux vers l'intérieur, encadrant un agent central de deux côtés.

Une colonne vertébrale, deux portes, un bord de rétroaction
Le schéma ci-dessous illustre la forme. Une personne définit l'intention ; Spécifications du kit specify et plan Les commandes transforment le tout en spécifications et en plan ; une personne les examine – à titre de point de contrôle, et non de document définitif. Trois détails déterminent si cela fonctionne réellement en pratique.
Tout d'abord, analyze s'exécute avant tout code. Il s'agit d'un contrôle de cohérence en lecture seule entre les spécifications, le plan et les tâches. L'instinct serait de le réserver pour la fin, mais Spec Kit… démarrage rapide personnel il est explicite que la première passe appartient avant implement, tant que les écarts sont encore peu coûteux à corriger. Vous pouvez relancer le processus par la suite pour vérifier la dérive si vous le souhaitez — mais la passe déterminante est celle qui précède l'écriture d'une ligne par l'agent.
En second lieu, une personne est propriétaire du test d'acceptation — la section suivante explique ce que cela signifie. Troisièmement, l'agent intègre tranches verticalesOn procède par petites portions de comportement, de bout en bout : un test unique qui échoue, le code nécessaire pour le réussir, un nettoyage, puis la portion suivante. Cette méthode évite de générer l’ensemble des tests d’emblée ou d’émettre des centaines de lignes simultanément, ce qui produit un code d’apparence plausible mais comportant des erreurs impossibles à localiser. De plus, le code n’est fusionné que lorsque les tests sont réussis, que la suite de tests a été vérifiée pour confirmer qu’elle détecte bien les bogues et que les tests validés n’ont pas été modifiés pour forcer leur réussite.
Un pipeline vertical allant de l'intention humaine à une porte de fusion, avec l'analyse comme porte de pré-codage, un test d'acceptation en lecture seule appartenant à l'humain, une boucle de code à tranches verticales et une arête de retour de la boucle vers la spécification.

Qui surveille les garde-fous ?
Il est facile de se représenter cela comme un flux simple « spécifications → tests → code » et de s'en tenir là. Le véritable enjeu de l'ingénierie réside dans les modes de défaillance, qui se résument tous à une seule question : si l'agent rédige les spécifications, rédige les tests, et Il écrit le code, mais qu'est-ce qui vérifie réellement quoi que ce soit ?
Qui décide de ce que signifie « correct » ?
Si un seul modèle génère les trois éléments (la spécification, les tests et le code), ils partagent le même angle mort. Une seule mauvaise interprétation de l'intention suffit à produire une spécification qui encode cette erreur, des tests qui la confirment et un code qui les réussit. Tout semble correct ; pourtant, tout est faux. Les deux encodages « indépendants » ne le restent que si Une personne en possède au moins un – chose que l'agent ne peut pas discrètement modifier.
Le meilleur élément à confier à une personne est le test d'acceptation — le test qui atteste que « cette fonctionnalité est terminée et fonctionne correctement ». Une spécification rédigée en prose peut être respectée à la lettre tout en étant enfreinte dans son esprit ; un test est une affirmation concrète, de type réussite ou échec. En assumer la responsabilité ne signifie pas rédiger manuellement chaque affirmation ; le mandataire peut élaborer les tests. Cela signifie qu’une personne les examine, approuve les affirmations et en reste responsable. avant qu'elles ne deviennent la référence par rapport à laquelle le code est évalué, plutôt que de laisser le même agent générer et fusionner silencieusement les siennes. En termes de tests, le test d'acceptation est votre oracle: l'élément qui détermine si le code est correct. Comme d'autres personnes travaillant sur ce sujet l'ont constaté, Les tests contrôlés par l'humain constituent le dernier rempart de défense — car, sous pression, l'agent a pour instinct de supprimer un test défaillant plutôt que de corriger le code. Si l'agent peut modifier l'oracle, alors l'oracle n'existe plus.
Le vert est un proxy, et les proxies sont manipulés.
« L'agent ne peut pas passer à l'étape suivante tant que le test n'est pas réussi » sonne comme une garantie. Ce n'en est pas une. Il existe de nombreuses façons de faire réussir un test sans pour autant atteindre son objectif : affaiblir ce qu'il vérifie, l'ignorer, remplacer le composant réel par un stub, coder en dur la réponse attendue, ignorer l'erreur, ou tout simplement réécrire le test. Le problème est classique : dès que « faire réussir les tests » devient le seul but, la réussite des tests cesse d'être un indicateur fiable du bon fonctionnement du système.
Il ne s'agit pas d'une hypothèse. Aider, un agent de codage en ligne de commande populaire et un choix judicieux pour la boucle de compilation, le fera par conception. Les tests de modification qu'il juge erronés sont en cause. Au lieu de forcer le code à s'y adapter, on évite de contourner le système. C'est certes utile lorsqu'une personne est aux commandes, mais cela représente une faille lorsque l'agent fonctionne de manière autonome. Comment empêcher l'agent de contourner le système ? Deux mécanismes de défense sont essentiels, et un simple résultat de réussite/échec n'en fait pas partie.

Ce que les tests ne peuvent pas dire
Les tests unitaires répondent à une question précise : cette fonction fait-elle ce que j’ai décrit, prise isolément ? Ils ne disent rien sur les performances, la sécurité, l’accessibilité, ni — plus important encore — sur la question de savoir si… Système Cela fonctionne réellement pour un utilisateur réel. C'est précisément là que le code généré par l'IA échoue : l'agent cible une unité isolée et interrompt discrètement le parcours de bout en bout qui la traverse. Il faut donc traiter Les tests de bout en bout et d'intégration doivent être considérés comme une priorité absolue, et non comme une simple formalité. — la couche qui pilote l'application réelle comme le ferait un utilisateur et qui détecte ce que les tests unitaires ne peuvent pas voir. Des outils comme Dramaturge MCP On peut même permettre à l'agent d'exécuter un véritable navigateur et de vérifier son fonctionnement par rapport à ce parcours, au lieu de se fier à des suppositions. Pour les exigences qui ne peuvent faire l'objet d'aucun test, intégrez-les explicitement comme contrôle dans votre pipeline de compilation : l'espoir ne saurait constituer un contrôle.
La refactorisation n'est pas optionnelle
La boucle TDD comporte trois étapes, et non deux : écrire un test en échec (rouge), le faire réussir (vert), puis nettoyer le code (refactorisation). Livré à lui-même, l’agent a tendance à négliger cette troisième étape et à déployer dès que le test réussit. Or, la refactorisation est essentielle pour garantir la qualité du code ; l’ignorer avec un agent rapide et infatigable, c’est précisément créer le désordre que tout le processus est censé éviter. Intégrez la refactorisation dans la boucle et surveillez les indicateurs de complexité ou de volume de code pour détecter les portions de code surdimensionnées par l’agent.
Le modèle est vivant, non figé.
Il existe une réelle tension entre les deux méthodes. Le SDD exige que les spécifications soient clairement définies avant même que le code ne soit écrit ; c’est tout l’intérêt d’un contrat. Le TDD, en revanche, est en partie une manière de… découverte La conception : on se rend souvent compte qu’une exigence était erronée, ou qu’une interface était maladroite, précisément au moment d’écrire le test correspondant. Alors, que se passe-t-il la première fois qu’un test révèle que la spécification elle-même était incomplète ?
La solution consiste à considérer les spécifications comme un document évolutif, et non comme une validation définitive. Lorsqu'une exigence change — ou qu'un test révèle une lacune —, on ne corrige pas le test pour qu'il corresponde au code ; on met d'abord à jour les spécifications (une petite modification validée), on met à jour les tests en conséquence, on constate leurs échecs, et on laisse l'agent les faire réussir. C'est le même cycle rouge-vert, appliqué aussi bien aux spécifications qu'au code — et il comporte une règle à ne surtout pas enfreindre : Les modifications du flux suivent le schéma suivant : spécification → test → code, jamais test → code de manière indépendante. Maintenir cette approche, c'est faire en sorte que les exigences changeantes cessent d'être le point faible de cette méthode et deviennent son point fort.
La porte vit dans l'environnement
Le choix clé en matière de conception est là où vit la disciplineIl est tentant d'en faire une propriété d'un outil spécifique — celui-ci planifie, celui-là code. Ne le faites pas. Placez le point de contrôle dans l'environnement — votre système de contrôle de version et d'intégration continue — plutôt que dans un agent unique. Une fois installé, l'agent de codage devient une pièce interchangeable plutôt qu'un élément auquel vous faites confiance.
Votre outil SDD est propriétaire de la structure de planification. Avec Spec Kit, c'est constitution → specify → clarify → plan → tasks → analyze → implementPlacez les règles TDD dans son fichier de constitutionRédigez un test défaillant avant l'implémentation ; ne marquez jamais une tâche comme terminée tant que les tests échouent ; ne modifiez jamais un test validé uniquement pour le faire réussir. Chaque commande hérite de ces règles, vous n'avez donc pas besoin de compter sur l'agent pour les mémoriser au cours d'une longue session.
Cette porte est un point d'entrée avant validation et une vérification d'intégration continue, et non une invite. Les tests réussissent, les mutations sont détectées, les tests validés restent intacts — c'est imposé par l'environnement, donc cela reste valable, que le code provienne de Spec Kit ou non. implement, d'Aider, ou de toute autre manière.
L'exécuteur est remplaçable. Originaire d'Aider --auto-test L'exécution en boucle offre un cycle de modification plus court qu'une commande par lots et répartit les modèles en fonction de leur coût : un modèle performant pour les spécifications et la planification, un modèle plus économique pour l'exécution en boucle à haute fréquence, avec mise en cache. À vous de choisir. La méthodologie est déterminante.
Adapter la cérémonie au risque
Un processus qui ne peut être réduit est abandonné. Une cérémonie complète — constitution de projet, spécifications, plan, répartition des tâches, sans oublier les tests de mutation — est excessive pour corriger un simple bug. Il faut donc procéder en deux temps, une séparation qui Documentation propre à Spec Kit recommande.

Les frais généraux sont-ils justifiés ?
Rien de tout cela n'est gratuit. Vous payez pour davantage d'appels de modèles, d'exécutions de tests et d'allers-retours que si vous laissiez un agent écrire le code en une seule passe. Il est donc légitime de se demander si ce surcoût est justifié. Pour une gestion rationnelle, il faut investir là où c'est vraiment utile : un modèle performant pour les spécifications et la planification, un modèle plus économique et plus rapide pour la boucle de compilation à haute fréquence ; n'exécuter les vérifications coûteuses, comme les tests de mutation, qu'à la fusion, et non à chaque itération ; et limiter la taille des tranches de code pour que chaque boucle reste peu coûteuse. Mais la vraie question est : à quoi comparez-vous votre approche ? La référence n'est pas un ingénieur senior écrivant un code impeccable, mais un agent non supervisé produisant un code plausible, mais défectueux, que vous déboguez ensuite pendant des heures. Face à cela, c'est la surcharge qui vous garantit un résultat fiable.
Quand ne pas faire cela
Et parfois, la réponse est tout simplement que cela n'en vaut pas la peine. Oubliez le processus complet pour les prototypes jetables et les tests rapides, dont le but est d'apprendre vite et de les abandonner. Oubliez-le aussi pour les modifications vraiment mineures, où la mise en place du test coûte plus cher que la correction du bug. Et soyez honnête concernant les domaines où il est impossible d'écrire un test pertinent à moindre coût : dans ces cas-là, les promesses sont vaines et les garanties ne sont que du théâtre. Den Delimarsky observe L'expérience pratique avec le kit de spécifications montre que les spécifications ne sont pas la solution miracle. Nommer ces limites n'est pas une excuse : c'est ce qui distingue une méthodologie d'un argumentaire commercial.
La barre vient de monter
Ce qui survit à l'automatisation, ce n'est pas le code lui-même. C'est savoir ce qu'il faut vouloir, le formuler avec suffisamment de précision pour qu'un génie trop rigide ne puisse pas se tromper, et être capable de vérifier si l'on a bien compris. Le SDD, c'est la façon de le formuler. Le TDD, c'est la façon de le vérifier.
L'agent supprimera allègrement vos tests pour faire disparaître l'erreur. Ainsi, les spécifications, la suite de tests et le jugement qui les sous-tend ne sont que des formalités superflues face au travail principal. Avec un agent impliqué, Ces le vrai travail.
Sources et outils
- Kent Beck parle du TDD, des agents d'IA et du « génie imprévisible » — L'ingénieur pragmatique
- Pourquoi les tests contrôlés par des humains constituent le dernier rempart — AllStacks
- Kit de spécifications GitHub — repo · démarrage rapide · constitution et les neuf articles
- Développement piloté par les spécifications avec Spec Kit — Microsoft pour les développeurs · L'analyse approfondie de Den Delimarsky
- Boucle de test d'Aider — test et vérification des peluches · options de référence
- Boucler la boucle de vérification de l'agent — Dramaturge MCP
Vous aimerez aussi
Qu'est-ce qui constitue une excellente plateforme de test ? Une liste de contrôle pour les équipes d'entreprise
Chaque équipe d'assurance qualité en entreprise finit par se heurter au même obstacle.
5 défis liés à la mise à l'échelle des tests que toute entreprise réglementée connaîtra (et comment les résoudre)
L'automatisation des tests à grande échelle est difficile à mettre en œuvre pour toute grande entreprise. Mais…
Votre équipe a adopté Maestro pour les tests mobiles. Et maintenant ?
Le cadre était une décision facile à prendre. L'infrastructure, en revanche, est une autre paire de manches. Maestro…