Du Test First Design au Test-Driven Development

Xavier Pigeon
Feb 14, 2019 · 5 min read

Un débat épineux fait rage depuis la nuit des temps — ou presque — à propos des tests unitaires de TDD. Voyons plutôt à côté de quoi tellement de développeurs et de passionnés sont passés. Remontons aux origines de TDD pour découvrir ensemble la vérité ! Tout un travail d’enquête ne sera pas de trop pour résoudre enfin cette triste et sombre histoire… J’indiquerai à la fin de l’article mes sources pour prouver et soutenir son contenu.

Aux prémisses de TDD, il s’agissait simplement d’écrire les tests avant de coder, et cela s’appelait Test First Design. Puis la méthode évolua vers une granularité plus fine de développement : pour une ligne de test en échec, une ligne de code de production est écrite pour faire réussir le test. Afin d’entériner cette granularité de ligne à ligne entre code de test et de code de production, trois lois ont émergé.

Parallèle avec les 3 lois de Képler
  1. Loi n°1 : “Vous ne pouvez pas écrire un code de production tant que vous n’avez pas écrit un test unitaire qui échoue.”
  2. Loi n°2 : “Vous ne pouvez pas écrire plus d’un test unitaire que nécessaire pour échouer, et ne pas compiler revient à échouer.”
  3. Loi n°3 : “Vous ne pouvez pas écrire plus de code de production que nécessaire pour que le test actuellement en échec réussisse.”

Ces lois sont ici énoncées selon les termes utilisés en 1999. Or l’emploi de l’expression “test unitaire” dans les deux premières lois prête ici largement à confusion. Par test unitaire, ces lois ne désignent pas un cas de test complet, mais en fait une unique assertion de test. Comment pourrait-on parler d’une granularité de ligne à ligne sinon ? Le cas de test complet devrait être obtenu après avoir itéré plusieurs fois l’ensemble de ces 3 lois, sachant que la résolution d’une erreur de compilation constitue déjà une itération à part entière. En 2014, Robert C. Martin reformule d’ailleurs les trois lois de TDD et le terme “unitaire” disparaît.

Une formulation exacte et exempte de toute ambiguïté serait plutôt comme suit.

  1. Loi n°1 : Vous devez écrire un test qui échoue avant de pouvoir écrire le code de production correspondant.
  2. Loi n°2 : Vous devez écrire une seule assertion à la fois, qui fait échouer le test ou qui échoue à la compilation.
  3. Loi n°3 : Vous devez écrire le minimum de code de production pour que l’assertion du test actuellement en échec soit satisfaite.

On fait ainsi la distinction entre l’assertion à l’origine de l’échec du test et le test qui échoue lors de son exécution. De plus, on ne présume pas de la forme de test la plus adéquate, ni ne se restreint à une seule possible, ce qui est d’autant plus pragmatique. Le fait de mettre bout à bout les 3 lois de TDD en une seule itération constitue ce qui est appelé un nano-cycle de TDD. À noter que ces 3 lois ne couvrent que les conditions à respecter en TDD pour arriver à un test qui réussit, en exprimant le minimalisme attendu du test en échec. Elles sont à la charnière des étapes de la phase amont de TDD, appelée Code-Driven Testing (à gauche dans le schéma ci-dessous).

Processus cyclique de TDD et micro-cycles itératifs de conception

À la lumière de ses origines, on comprend mieux que TDD n’est pas défini par le choix des tests unitaires, qu’inversement les tests unitaires ne sont pas non plus définis par la pratique de TDD. De fait, TDD n’émet pas de restriction sur les formes de test à mettre en œuvre, et le fait de recourir successivement à différentes formes de test ne signifie en aucune manière que nous cessons brutalement d’appliquer TDD. Tout en appliquant TDD, il est en vérité tout aussi intéressant de s’appuyer sur des tests unitaires, des tests d’acceptation métier, des tests d’intégration de composant, des tests d’intégration système, et finalement n’importe quel test susceptible d’influencer positivement la conception du logiciel. Car rappelons-le : TDD n’est pas une méthode de test, mais bien une méthode de conception, qui s’appuie sur des tests.

Par conséquent, il est vain et inapproprié de chercher à redéfinir la notion de test unitaire en considération d’une interprétation quelconque de TDD. S’il existe deux formes de test qui n’ont pas la même taille de sujet de test ou qui ne poursuivent pas les mêmes objectifs de vérification, il est simplement normal qu’elles portent des noms différents. Pour rappel, la notion d’unité dans les tests unitaires vient du fait qu’un test unitaire porte sur une unité de programmation, une et une seule. Une unité de programmation est définie en fonction du paradigme de programmation. Ainsi :

En corollaire, si le sujet de test est plus gros qu’une unité de programmation, alors le test n’est pas unitaire. Un test qui vérifie le respect d’une règle métier en instanciant plusieurs objets pour constituer son sujet de test est un test d’acceptation métier.

Plus généralement, l’étude et l’analyse des formes spécifiques de test, autrement dit la typologie des tests, n’est pas dans le giron du Software Craftsmanship, pas davantage que les stratégies de test ne le sont. Le Software Craftsmanship est une mouvance de l’ingénierie logicielle qui fédère une communauté de professionnels autour de méthodes de conception et de méthodes collaboratives pour produire des logiciels utiles et de grande qualité, dans le cadre de partenariats. Ces méthodes de conception s’appuient généralement sur les tests automatisés, et plus précisément des pratiques de test, mais elles ne distinguent pas les différentes formes de test entre elles, et ce n’est pas leur préoccupation. Il est tout au plus question de doublures de test (simulacre, bouchon, espion de test, etc). Et cela vaut évidemment pour TDD.

Or les pratiques de test du Software Craftsmanship ne manquent pas et forment un terrain propice à l’exploration pour tous les aventuriers du code avides d’excellence, comme en témoigne l’infographie que je vous propose ci-après.

Pratiques de TDD, avec ses 3 lois actualisées

Références

  • Clean Code, A Handbook of Agile Software Craftsmanship, Robert C. Martin, p. 122
  • The Cycles of TDD, Robert C. Martin

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade