Skip to Content

Chapitre 11.4 — Tests & TDD avec l’IA

⏱️ TL;DR — Le TDD (écrire le test avant le code) est particulièrement puissant avec l’IA : un test qui échoue est à la fois une spec précise de ce que tu veux, et une preuve non falsifiable que l’agent doit faire passer (il ne peut pas « prétendre » que c’est fait). La boucle rouge → vert → refactor cadre l’agent : le test d’abord définit le but, le code ensuite le satisfait, la refacto nettoie sous filet. Piège à éviter : des tests qui miment l’implémentation au lieu de vérifier le comportement.

🎯 Objectifs

  • Comprendre pourquoi le TDD s’accorde si bien avec l’IA.
  • Piloter la boucle rouge → vert → refactor.
  • Écrire des tests de comportement, pas d’implémentation.
  • Savoir quand TDD vs test-après.

Pourquoi le TDD marche si bien avec l’IA

Deux propriétés du test-first se combinent idéalement avec un agent :

  1. Le test est une spec exécutable. Un test qui décrit « deleteTask(id) retire la tâche de la liste et renvoie le nouvel état » est plus précis qu’un paragraphe de prompt. Tu passes de « fais à peu près ça » à « fais exactement passer ça ». C’est le meilleur ancrage possible (5.1).
  2. Le test est une preuve non falsifiable. On a vu (5.4) que « ça devrait marcher » ne suffit pas. Un test rouge à faire virer au vert est une condition de fin objective que l’agent ne peut pas contourner : soit il passe, soit il ne passe pas. Combiné au hook Stop (P7), c’est mécanique.

La boucle rouge → vert → refactor

  • Rouge : écris (ou fais écrire) un test qui décrit le comportement voulu. Il échoue (le code n’existe pas encore). Vérifie qu’il échoue pour la bonne raison.
  • Vert : écris le minimum de code pour le faire passer. Pas plus — on ne code pas de features non testées.
  • Refactor : nettoie la structure, tests toujours verts (11.3).

Avec l’agent, un prompt TDD ressemble à :

« En TDD : écris d’abord le test de deleteTask (retire la tâche, revalide la liste) — montre-le rouge. Puis implémente le minimum pour le passer vert. Puis propose un refactor si utile, tests verts. »

Tu vois la progression : rouge (la cible), vert (atteinte), refactor (propre). Chaque étape est vérifiée.

💡 Réflexe d’architecte — Le test d’abord te force à répondre à « qu’est-ce que je veux, exactement ? » avant de laisser l’agent coder. C’est le meilleur antidote au flou (2.1) : au lieu d’un critère vague, tu as un critère exécutable. Souvent, écrire le test clarifie le design mieux qu’une longue réflexion.

Le piège : tester l’implémentation, pas le comportement

⚠️ Piège — Laisser l’agent écrire des tests qui décalquent l’implémentation (« la fonction appelle prisma.task.delete avec tel argument ») plutôt que le comportement (« après suppression, la tâche n’est plus dans la liste »). Un test qui mime l’implémentation : (1) casse dès qu’on refactore (alors que le comportement est intact — il tue le refactor, 11.3), et (2) ne prouve pas grand-chose (il vérifie que le code fait ce que le code fait). Exige des tests orientés comportement : entrées → sorties/effets observables, pas « telle fonction interne est appelée ».

Consigne utile à l’agent : « teste le comportement observable (ce que voit l’appelant/l’utilisateur), pas les détails internes. Le test doit survivre à un refactor qui préserve le comportement. »

TDD toujours ? Non — à bon escient

Le TDD brille quand le comportement est clair et l’enjeu réel : logique métier, server actions, calculs, cas limites. Il est moins adapté à l’exploratoire (tu ne sais pas encore ce que tu veux — prototype d’abord, 4.4) ou au purement visuel (là, c’est la vérif visuelle, P10, qui prime). Règle : TDD quand tu peux formuler le comportement attendu ; test-après (ou vérif visuelle) quand tu explores ou que c’est du rendu.

🧭 Sur TaskFlow — Les server actions de TaskFlow (create/update/delete) sont des cas TDD parfaits : comportement clair, testable, à fort enjeu (elles écrivent en base). On les a construites test-first en 5.5, et le hook Stop (P7) garde ces tests verts. Pour l’UI, on complète par la vérif visuelle Playwright (P10). Chaque type de code reçoit la vérification qui lui convient.

✏️ Exercices

Exercice 1 — Une action en TDD. Prends une fonction à comportement clair. Fais écrire son test rouge d’abord (vérifie qu’il échoue pour la bonne raison), puis le code vert. Le test décrit-il le comportement ou l’implémentation ?

✅ Solution

Un bon test décrit entrées → sorties/effets observables (« après X, l’état est Y »), pas les appels internes. S’il mentionne des détails d’implémentation, réécris-le : il doit survivre à un refactor. Le test rouge d’abord te fait clarifier le comportement voulu avant tout code.

Exercice 2 — Chasse au test-implémentation. Relis 3 tests existants de ton projet. Combien testent l’implémentation (appels internes, mocks du monde interne) plutôt que le comportement ? Réécris-en un.

✅ Solution

Beaucoup de suites contiennent des tests fragiles qui décalquent l’implémentation et cassent à chaque refactor. Les réécrire en tests de comportement les rend robustes (ils survivent aux refactors) et utiles (ils prouvent quelque chose). C’est un investissement qui débloque le refactoring (11.3).

🧠 Quiz de révision

1. Pourquoi le TDD s’accorde-t-il si bien avec l’IA ?

Parce qu’un test rouge est (1) une spec exécutable précise (meilleur ancrage qu’un prompt flou) et (2) une preuve non falsifiable que l’agent doit faire passer — condition de fin objective, mécanisable via le hook Stop.

2. Décris la boucle rouge → vert → refactor.

Rouge : un test qui échoue et décrit le comportement voulu. Vert : le minimum de code pour le passer. Refactor : nettoyer sous filet, tests verts. Chaque étape est vérifiée.

3. Comportement vs implémentation : lequel tester, et pourquoi ?

Le comportement observable (entrées → sorties/effets). Un test qui mime l’implémentation casse à chaque refactor (il tue le refactor) et ne prouve rien d’utile. Le test doit survivre à un refactor qui préserve le comportement.

4. Le TDD convient-il à tout ?

Non : idéal quand le comportement est clair (logique, actions, calculs) ; moins adapté à l’exploratoire (prototype d’abord) ou au visuel (vérif visuelle P10). On choisit la vérification selon le type de code.

5. En quoi le test-first clarifie-t-il le design ?

Parce qu’il force à répondre à « qu’est-ce que je veux, exactement ? » avant de coder. Écrire le test transforme un critère flou en critère exécutable, et clarifie souvent le design mieux qu’une longue réflexion.


Chapitre suivant : CI, sécurité & industrialisation — verrouiller la qualité au-delà de ta machine.