Test driven development

Un article de Wikipédia, l'encyclopédie libre.
Sauter à la navigation Sauter à la recherche

Le Test-Driven Development (TDD), ou développements pilotés par les tests en français, est une méthode de développement de logiciel qui consiste à écrire chaque test, notamment des tests unitaires, avant d'écrire le code source d'un logiciel, de façon itérative.

Cycle de TDD[modifier | modifier le code]

Cycle global TDD
Une représentation graphique du cycle de la méthode Développements Pilotés par les Tests (TDD)

Le cycle préconisé par TDD comporte cinq étapes :

  1. écrire un seul test qui décrit une partie du problème à résoudre ;
  2. vérifier que le test échoue, autrement dit qu'il est valide, c'est-à-dire que le code se rapportant à ce test n'existe pas ;
  3. écrire juste assez de code pour que le test réussisse ;
  4. vérifier que le test passe, ainsi que les autres tests existants ;
  5. puis remanier le code, c'est-à-dire l'améliorer sans en altérer le comportement.

Ce processus est répété jusqu'à résoudre le problème d'origine dans son intégralité.

Intérêt[modifier | modifier le code]

Les tests tels qu'ils sont mis à profit dans TDD permettent d'explorer et de préciser le besoin, puis de spécifier le comportement souhaité du logiciel en fonction de son utilisation, avant chaque étape de codage. Le logiciel ainsi produit est tout à la fois pensé pour répondre avec justesse au besoin et conçu pour le faire avec une complexité minimale. On obtient donc un logiciel mieux conçu, mieux testé et plus fiable, autrement dit de meilleure qualité.

Quand les tests sont écrits après codage, comme c'est le cas traditionnellement, les choix d'implémentation contraignent l'écriture des tests : les tests sont écrits en fonction du code, et si certaines parties du code ne sont pas testables, elles ne seront pas testées. Au contraire, en testant avant de coder, on utilise le code avant son implémentation, de sorte que les contraintes définies par les tests sont imposées à l'implémentation : le code est écrit en fonction des tests. Le fait d'écrire les tests avant le code en TDD est donc à l'origine d'implémentations testables, c'est-à-dire facilement testables et testables à 100%. Or la testabilité du code favorise une meilleure conception par un couplage lâche et une cohésion forte, ce qui évite des erreurs communes de conception.

Comme chaque test correspond à un changement minimal de code, un test permet de faire un lien évident entre une régression et sa source s'il échoue. Ce lien fait de l'exécution des tests un moment charnière dans un cycle TDD : on capture l'état instantané du logiciel et on détecte d'éventuelles régressions suite au dernier changement. En effet, on veut à tout prix éviter de modifier le code en présence d'une régression. Le cas échant, on ne saurait pas dire avec certitude si les tests en échec le sont à cause du changement actuel ou d'un changement précédent. C'est en cela que les tests déjà écrits constituent un harnais contre des accidents de parcours, où l'on perdrait le lien entre changement et régression. La présence d'un tel harnais permet donc d'envisager avec sérénité n'importe quel changement de code, qu'il s'agisse d'une transformation (modification qui affecte le comportement), ou d'un remaniement (modification qui n'altère pas le comportement), ainsi que les livraisons du logiciel de version en version.

L'enjeu des remaniements cycliques du code est de réaligner la conception du code avec les besoins connus, afin de lutter contre l'entropie logicielle et de prévenir la dette technique. Changer la conception du code sans en altérer le comportement requiert de disposer de tests qui garantissent l'absence de régression. Pour cela, on devrait faire appel à différentes formes complémentaires de test, de manière à ne pas les réécrire à chaque remaniement de code, quelle que soit l'étendue des remaniements : tantôt des tests pour vérifier les résultats exacts d'un traitement, tantôt des tests pour vérifier que des composants collaborent correctement, sans que ces différents tests ne cassent ensemble pour les mêmes raisons.

Comme les tests sont écrits avant codage, ils trouvent plusieurs emplois dans TDD : ils servent d'abord à résoudre un problème en guidant le codage à chaque étape, ils fournissent ensuite un harnais de tests contre les régressions, enfin ils documentent le comportement du logiciel. Grâce à son utilisation des tests, TDD fait gagner en productivité à plus d'un titre.

  • TDD permet d'éviter des modifications de code sans lien avec le but recherché, car on se focalise étape par étape sur la satisfaction d'un besoin, en conservant le cap du problème d'ensemble à résoudre.
  • TDD permet d'éviter les accidents de parcours, où des tests échouent sans qu'on puisse identifier le changement qui en est à l'origine, ce qui aurait pour effet d'allonger la durée d'un cycle de développement.
  • TDD permet de maîtriser le coût des évolutions logicielles au fil du temps, grâce à une conception du code perméable au changement.
  • TDD permet de s'approprier plus facilement n'importe quelle partie du code en vue de le faire évoluer, car chaque test ajouté dans la construction du logiciel explique et documente le comportement du logiciel en restituant l'intention des auteurs.
  • TDD permet de livrer une nouvelle version d'un logiciel avec un haut niveau de confiance dans la qualité des livrables, confiance justifiée par la couverture et la pertinence des tests à sa construction.

Programmation binomiale en TDD[modifier | modifier le code]

Lorsque deux personnes s'associent en binôme pour résoudre un problème de programmation, elles occupent tour à tour deux rôles semblables à ceux d'un équipage de rallye automobile : le pilote, qui tient le clavier, code, tandis que le copilote supervise, prend du recul et guide son pilote par étapes, puis les rôles sont échangés à intervalles réguliers. En appliquant TDD, un binôme peut échanger les rôles de différentes façons : soit entre deux cycles de développement au moment d'itérer, soit entre l'écriture d'un nouveau test en échec et le codage d'un nouveau comportement. La seconde façon d'échanger les rôles force à séparer les préoccupations du test de celles de l'implémentation et met le copilote à contribution pour écrire le test seulement, tandis que la première permet de dérouler un cycle complet en occupant un même rôle.

Voir aussi[modifier | modifier le code]

Sur les autres projets Wikimedia :

Articles connexes[modifier | modifier le code]

Bibliographie[modifier | modifier le code]

  • (en) Kent Beck, Test Driven Development: By Example, Addison-Wesley, , 240 p. (ISBN 0-321-14653-0)
  • (en) Lasse Koskela, Test Driven: TDD and Acceptance TDD for Java Developers, Manning, , 470 p. (ISBN 1-932-39485-0)

Liens externes[modifier | modifier le code]