Le Test Driven Development est certainement la méthode de design de code la plus efficace connue actuellement ! Cependant, malgré son incroyable efficience, elle est souvent très mal comprise (voir prise pour une méthode de test).
Cette incompréhension vient certainement de la grande difficulté de son apprentissage, le TDD étant certainement une des plus belles illustration de la Loi de Bushnell : "Easy to learn, hard to master".
Il existe de très nombreuses manières d'apprendre le TDD, je vais simplement donner ici les astuces que j'aurais aimé avoir quand j'ai commencé mon propre apprentissage.
La théorie
Commençons par le commencement : Le TDD c'est quoi ? Déjà une méthode de design (même si je l'ai déjà dit) mais c'est surtout une manière d'organiser son travail qui se découpe dans un cycle très court en trois phases :
On commence par RED. Dans cette phase, on va écrire un test qui ne passe pas (s’il ne compile pas, il ne passe pas). À ce moment, on ne se concentre que sur la logique des APIs (exposition des methods, organisation des classes) que l'on veut appeler : est-ce que si j'appelle cet Objet de cette manière cela traduit bien l'intention métier du traitement que je veux faire ?
Vient ensuite la phase GREEN, ici on va écrire le code le plus direct pour faire passer notre test (sans casser un test précédent).
On termine le cycle avec REFACTOR où on va retravailler notre code pour :
- Avoir du code plus élégant ;
- Mieux expliciter les traitements qui sont faits ;
- Apporter une meilleure réponse au métier.
On répète ce cycle toutes les quelques secondes voire minutes. Il n'est absolument pas question ici de cycle sur plusieurs jours. On fait plusieurs centaines de cycles de TDD dans une journée !
Ce cycle très simple à décrire peut cependant être très perturbant quand on s'y essaie pour la première fois. Une des erreurs les plus courantes est de vouloir penser à la manière de faire l'implémentation quand on est dans la phase RED. Il est aussi courant de vouloir faire tous les tests d'une class avant de se lancer dans l'implémentation : ce faisant notre implémentation ne sera alors pas dirigée par les tests !
Quand on commence le TDD, les journées sont tout bonnement épuisantes tant cette manière de travailler peut sembler peu naturelle. Au début, on fait peu de choses pendant la phase de REFACTOR alors que cette phase est au moins aussi importante que les deux autres, aussi je pense qu'il faut y prêter une attention particulière dans les premiers temps (penser à refactorer le code mais aussi les tests par exemple).
Cependant, une fois maîtrisé, le TDD permet d'obtenir très rapidement du code de très bonne qualité avec des efforts réduits. Je n'ai pas de statistiques précises mais, de mon expérience, il est tout bonnement impossible pour un développeur ne pratiquant pas le TDD de s'approcher de la vélocité d'un développeur travaillant en TDD !
Bien, ce court rappel étant fait (le but de l'article n'étant pas de présenter ou de convaincre de l'utilité de la méthode), voyons maintenant comment l'apprendre.
Gagner du temps dans son apprentissage
Même s'il est tout à fait possible d'apprendre seul le TDD, il sera beaucoup plus facile de bénéficier de l'expérience de nos pairs qui ont déjà fait cet apprentissage.
Un excellent moyen est de trouver une personne pouvant vous accompagner dans votre quotidien. Si cette personne n'existe pas dans votre entreprise, vous pouvez peut-être faire intervenir un prestataire ?
Vous pouvez peut-être aussi participer aux meetups des crafters de votre ville (si vous habitez à proximité d'une grande ville il y a surement un groupe).
Vous pouvez aussi lire des livres sur le sujet (Test Driven Development: By Example ou Working Effectively with Legacy Code) ou participer à des conférences.
Dans tous les cas et comme pour tous les apprentissages, pensez à remettre régulièrement en question les enseignements que vous allez recevoir sur ce sujet. Encore une fois, le TDD est malheureusement très mal compris et beaucoup penseront bien faire en parlant uniquement de test first.
Commencer par des exercices simples
Quand j'ai commencé le TDD, je l'ai fait sur la base de code sur laquelle je travaillais à ce moment-là (une application Struts avec des méthodes atteignant facilement les milliers de lignes). Avec le recul, je pense que j'aurais adoré connaître l'existence des code katas pour m'essayer doucement à cette nouvelle approche.
La métaphore des code katas vient des arts martiaux, on les pratiques dans des Coding Dojo et, comme pour les kata dans les arts martiaux, ils sont fait pour être répétés plusieurs fois jusqu'à la maîtrise d’une technique donnée.
Les katas permettent donc de s'entraîner à différentes techniques, pour le TDD je vous conseille (dans cet ordre) :
- FizzBuzz ou Leap Years ;
- String Calculator ;
- Word Wrap ;
- Bowling Game (attention il y a une grande marche par rapport au précédent) ;
- Roman Numerals.
Et si vous voulez vous entraîner de manière plus spécifique aux techniques de refactoring :
- Tennis ;
- Gilded rose (mon grand favoris) ;
- Trivia.
Je ne peux que trop vous conseiller de faire ces katas puis de vous entraîner à les refaire régulièrement. Trivia mis à part, tous les katas de cette liste sont faisables en moins de 10 minutes donc n'hésitez pas à utiliser des petits moments morts de la journée (retour de déjeuner, avant une réunion, etc) pour en faire rapidement un.
Quand vous serez suffisamment à l'aise en TDD sur des petits exercices, vous pourrez commencer à inclure cette technique dans votre quotidien !
Au quotidien
Une question qui m'est souvent posée est : "Je veux faire du TDD mais je suis sur un code legacy pas vraiment testable, comment je fais pour commencer ?". Dans ce genre de cas je répond : "Ne commence pas sur ce code !".
En fait, réussir à tester ce type de code demande un peu d'expérience en TDD et, pour commencer, je vous conseille plutôt d'appliquer la technique sur du nouveau code que vous allez faire. Créez des classes très simples qui répondront à un besoin précis et faites-les en TDD.
Lorsque vous allez commencer le TDD, vous serez en phase d'apprentissage, et, scoop : ON NE VA PAS VITE QUAND ON APPREND ! Aussi frustrant que cela puisse être, vous allez perdre en vélocité pendant votre apprentissage. Il faut être prêt à l'accepter.
De mon côté, ayant appris le TDD seul et dans un contexte difficile, j'ai certainement fait le plus mauvais choix possible : j'ai fait des heures (beaucoup - trop - d'heures) pour pallier à cette perte de vélocité. Je ne conseille vraiment pas cette approche, je pense qu'il est beaucoup plus efficace de transitionner progressivement vers le TDD et de rattrapper le temps à apprendre sur le temps où l’on travaille "comme avant". Enfin, en fait je n'en sais rien. C'est à vous de trouver comment faire. Sachez cependant que vous allez perdre en vélocité pendant un certain temps (Allant, je pense, d'un mois en étant très bien accompagné à… beaucoup plus).
Pendant cette phase de votre apprentissage, il faudra non seulement s'approprier la technique mais aussi tous les outils et patterns permettant de tester efficacement du code. Aussi, je pense que le temps nécessaire peut grandement changer en fonction des technologies que vous utilisez. Sur des technologies peu matures, vous devrez certainement vous fabriquer vos propres outils !
Cependant, si vous vous accrochez, vous allez atteindre le point d'équilibre : ce moment où votre vélocité sera la même en faisant du TDD que sans faire de tests.
Le point d'équilibre
Bien sûr, il ne s'agit pas réellement d'un point dans le temps, personne n'a de métrique suffisamment précise de sa vélocité pour pouvoir dire "c'est arrivé le 4 Mai 2012 à 13h37, je me rappelle très bien c'était un vendredi !".
Il s'agit plus ici d'un ressenti général, d'un moment où l’on fait encore du code sans TDD "par habitude" mais à chaque fois, on se dit qu'on a quand même perdu du temps… C'est à partir de ce moment que le TDD devient une évidence dès que l'on fait du code.
A partir de là, les choses s'accélèrent (en tout cas c'est le ressenti que j'en ai eu). On commence à apprendre BEAUCOUP plus vite, tout devient plus facile de jour en jour. Très rapidement, les points techniques qui nous semblaient être la principale difficulté dans la réalisation d'une application (connexion à la persistance, échanges avec d'autres services, …) ne deviennent qu'un détail que l'on ne prend maintenant que vaguement en compte dans nos chiffrages !
Pour moi, c'est à partir de ce point que le travail précédent a commencé à payer. Je ne sais pas dire précisément mais il m'a fallu quelques mois pour en arriver à ce point. Ces mois ont été compliqués pour moi car je n'étais pas sûr de mon choix. Je n'avais aucun mentor, aucun collègue travaillant de cette manière et qui aurait pu me conforter sur les gains de cette méthode de travail.
Aujourd'hui, je suis très content d'avoir investi du temps et de l'énergie dans l'apprentissage du TDD puisque c'est, sans conteste, un des skills qui me facilite le plus le quotidien.
Vers la qualité et la vélocité
Plus on avance dans la maîtrise de TDD, plus on avance dans la maîtrise globale des techniques de notre industrie, aussi je ne peux que trop vous conseiller d'essayer :
- No estimates: vraiment, le gain de temps et d'énergie est phénoménal ;
- Le Domain Driven Design: c'est une grosse marche avec un ticket d'entrée très cher mais ça en vaut, là aussi, largement la peine.
De mon côté, je suis certainement au début d'un chemin dont je ne connais pas encore l'existence. Tout ce que je sais, c'est que j'ai hâte de découvrir toutes ces techniques et approches qui rendront mon quotidien encore plus amusant !