Les Concombres mangent-ils des Pythons ? (première partie)

Mar 06 octobre 2009

L'une des pièces maîtresses du développement moderne est le "Test-Driven Development", le développement dirigé par les tests. Cette méthodologie a pour principe de "blinder" les programmes et les modules écrits en testant au maximum toutes les entrées / sorties possibles. Toutes les fonctions sont testées, à la fois dans le cas "qui marche", mais également dans le cas "qui ne marche pas". On essaie ainsi d'anticiper le comportement d'un programme dans le cas où on lui adresserait des données erronées. Imaginons, par exemple que pour un blog, on crée une page qui affiche une catégorie. Si la catégorie existe, on affiche les articles rattachés à celle-ci.
Pour tester ce comportement, on commence par écrire le test. Cette étape est très importante. Toujours commencer par écrire le test en relation avec la fonctionnalité. Puis on le lance. Il échoue (puisque a priori on n'a encore rien fait concernant cette page). Puis on commence à implémenter la fonction. On code, on teste, on code, on teste, on code, on teste... jusqu'à ce que le test affiche un beau "oui, ça y est, ça fonctionne".

Ce qui est "magique" avec le TDD, c'est qu'en écrivant le test "qui marche", on pense de suite aux tests "qui ne marchent pas". Et c'est là qu'on commence à imaginer les scénarios suivants : la catégorie existe, mais il n'y a pas d'article correspondant, la catégorie demandée n'existe pas, etc.

Et on redémarre, on écrit le test, c'est à dire la description "programmatique" du comportement du programme dans ce cas précis. Par exemple, "si la catégorie n'existe pas, on doit renvoyer une page 404 NOT FOUND" (c'est le comportement classique). Mais on peut très bien décider de faire autrement, d'envoyer une page qui récapitule les catégories existantes, pour que l'internaute puisse cliquer sur celle qui lui plaît...

C'est extrêmement intéressant de développer en écrivant ce type de scénarii, parce que ça fait réfléchir. Au fur et à mesure qu'on construit l'application, on la consolide, en imaginant ce qu'un utilisateur peut injecter dans cette application. Et on se surprend même à penser à des cas auxquels on n'aurait jamais pensé sans avoir pris ce recul nécessaire sur le fonctionnement interne de nos programmes.

Bon, un petit dessin vaut mieux qu'un long discours :

TDD source: Wikipedia
Test Driven development flowchart - source: Wikipedia

On profite également de cette méthode pour renforcer la qualité du produit fini : en effet, dès lors qu'on intègre une nouvelle fonctionnalité ou qu'on modifie le comportement d'un morceau du programme, on repasse l'intégralité des tests. Oui. On relance tout, toute la chaîne. Et si tout passe, c'est que la modification introduite n'a pas modifié le reste. Qu'on a gardé une sorte d'intégrité au programme dans son entier. Si on introduit un changement dans une fonction précédemment implémentée, on le voit immédiatement ; et il faut agir en conséquence pour boucher la faille.

Bien évidemment, ce qui est vrai pour une application web l'est tout autant pour tout type d'application. À partir du moment où l'on dispose d'un outil de test automatique, on gagne énormément à l'utiliser en mode TDD.

Et tu me diras... "et les concombres, alors ?"

Patience... Ce sera pour une prochaine fois...