Introduction
Dans cet article, je vais vous livrer un avis très personnel sur ce que m’a apporté le TDD et les difficultés que j’ai pu rencontrer. Si vous ne savez pas ce qu’est le Test Driven Development, je vous conseille cette vidéo qui est très bien faite : https://www.youtube.com/watch?v=wMY5FE59rkI
Comment j’en suis venu au TDD ?
J’ai eu beaucoup de chance de faire une licence professionnelle où le Software Craftsmanship était mis en avant et où on a pu avoir une introduction sur ce sujet. Ca a piqué ma curiosité et je suis allé en meetup pour essayer d’en apprendre davantage sur le sujet.
Je me souviens de m’être senti un peu perdu, déjà de faire le test en premier mais aussi et surtout de ne pas réfléchir à l’implémentation finale avant de faire le test.
C’est cette mécanique que je trouve difficile à appréhender, autant faire du “test first” est assez intuitif, (on change simplement l’ordre dans lequel on rédige nos tests unitaires), autant le TDD apporte une façon de penser complètement différente. Il faut faire l’implémentation la plus simple pour faire passer notre test rouge au vert, refactorer et voir émerger le design, ce n’est pas évident du tout !
Lorsque j’ai vu la correction d’un Kata en TDD par quelqu’un qui était très expérimenté dessus, ça a été une claque dans la figure. C’est une chose d’avoir lu que la méthodologie était efficace, s’en est une autre de la voir véritablement en action et de voir de façon naturelle, du code de qualité apparaître et répondre au besoin. Toutes mes questions sur la vélocité s’étaient évanouies car le kata avait été plié en 10min et j’ai commencé à saisir la puissance du TDD. A la sortie de la session je voulais absolument utiliser cette méthodologie au quotidien pour pouvoir, moi aussi, faire rapidement du code fiable, propre, et bien conçu.
Comment j’ai appris à faire du TDD ?
Tout d’abord, je pense pas qu’on puisse maîtriser le TDD avec seulement un an d’utilisation et ça serait prétentieux de ma part de dire que je fais “bien” du TDD. C’est vraiment une technique “easy to learn”, “hard to master” à mon sens.
Pour pouvoir l’appliquer sans impact négatif sur ma vélocité, il m’a fallu le travailler à de nombreuses reprises dans des Kata en étant accompagné par des personnes expérimentées qui m’ont partagé leurs conseils. Pour moi, c’est essentiel d’être accompagné par des personnes expérimentées ou de regarder ces personnes en faire. En effet, il est difficile de se rendre compte tout seul si on a des tests trop proches de l’implémentation (et pas assez du comportement), si on a fait des tests trop peu pertinents ou qu’on a trop anticipé l’implémentation. Il faut également être à l’aise avec tout ce qui touche au test et là encore, il n’y a pas de secret il faut pratiquer.
Pour résumer, j’ai appris l’essentiel de ce que je sais sur le TDD lors de Kata réalisés en meetup avec des développeurs expérimentés et en retravaillant des Kata de mon côté. Une fois que je me suis senti un peu plus à l’aise, j’ai pu l’expérimenter sur des tâches simples (lorsqu’il fallait créer un service sans dépendance par exemple).
Quelles difficultés pour le TDD ?
Le TDD n’est pas une pratique généralisée parmi les développeurs. Même sur des profils expérimentés, j’ai rencontré très peu de candidats qui utilisaient cette méthodologie au cours des nombreux entretiens que j’ai été amené à faire passer cette année. C’est le même constat lorsque j’en discute avec mes amis développeurs: s’ils en ont entendu parler, ils sont assez convaincus que cette méthodologie est pertinente mais ils ne l’utilisent pas au quotidien. Pourquoi? Parce que leur code est legacy et ils font plus de “bug fix” que de features ou alors ils n’ont déjà pas le temps de faire des tests unitaires alors se former au TDD, ça semble impossible.
De mon point de vue, ces constats illustrent une difficulté que j’ai eu lorsque j’ai commencé à essayer d’en faire: c’est compliqué à appliquer dans des cas réels sans perdre de vélocité au début. Je dis dans l’article que j’utilise le TDD au quotidien depuis un an, mais il m’a fallu au moins un an avant ça pour pouvoir être assez à l’aise avec le TDD. En résumé, pour moi, le principal défaut du TDD est son coût d’entrée. Il m’a fallu le pratiquer au travers de Kata avec des personnes expérimentées pour commencer à comprendre, l’utiliser dans des cas simples dans la vie de tous les jours pour enfin, en faire quotidiennement.
Il a fallu aussi que je progresse en refactoring pour pouvoir l’appliquer dans 100% des cas. En effet, il est parfois difficile de faire des tests unitaires dans certaines parties des applications legacy (lorsqu’il y a énormément de dépendances par exemple). Dans ces cas là, il faut refactorer la ou les classes en question de façon safe afin de pouvoir faire simplement des tests unitaires. Le refactoring de façon “safe” s’apprend aussi mais il a fallu là aussi un investissement en meetup pour apprendre diverses techniques (golden master, mutation testing etc..) et je n’en suis qu’au début.
Quel gain ?
J’ai l’impression de faire du code de meilleure qualité, il est bien testé et ma vélocité est jugée comme satisfaisante. Je ne peux pas dire si je suis plus rapide ou non grâce au TDD car j’ai progressé sur d’autres points en parallèle.
– Du code bien testé
Quand je dis bien testé, c’est que la couverture de code et la robustesse (cf. https://apero-tech.fr/mutation-testing-par-lexemple/) de mes tests ont augmenté drastiquement lorsque je réalise une feature
– Du code de meilleure qualité
Par feignantise, le code produit sera de meilleure qualité, je m’explique:
Lorsque du code de mauvaise qualité est introduit, c’est souvent (je pense) par flemme. C’est très facile d’injecter des Services, DAO même s’ils ne sont pas forcément nécessaires pour remplir le besoin. On ne va pas se préoccuper du nombre de paramètres d’une fonction, ni de sa taille ou si elle retourne une valeur.
Quand on fait du TDD, s’il n’y a pas de valeur de retour, on ne peut pas tester donc on en met. S’il y a trop de paramètres à une méthode alors c’est difficile de tester donc on s’arrange pour en avoir moins. Quand une méthode fait trop de choses, là aussi c’est dur à tester, du coup on préfère avoir des méthodes courtes, spécifiques qui ont un rôle bien défini. Je pense que vous voyez où je veux en venir, et c’est une des grandes forces du TDD à mon sens: il ne faut pas se forcer à faire du code propre, on va en écrire naturellement.
– Une meilleure gestion des interruptions quotidiennes
Les interruptions dans la vie de tous les jours me font perdre moins de temps: avant lorsque quelqu’un me coupait dans mon travail, il me fallait du temps pour me replonger sur ce que j’étais en train de faire. Aujourd’hui lorsqu’on m’interrompt, je suis en train d’écrire ou de faire passer un test spécifique, je n’ai pas besoin de réfléchir à ce que je faisais et mine de rien c’est un gain de confort et d’efficacité !
– Des erreurs détectées plus tôt
On sait que plus un bug est détecté tard, plus il est cher à réparer, pour moi c’est aussi vrai dans le cycle de développement: si tu écris une ligne de code et que tu as instantanément un test qui passe au rouge, tu sais que c’est ta ligne qui l’a fait casser et tu corriges tout de suite. Dans le cas contraire, si le seul moment de feedback de test que tu as, c’est avec la CI lorsque tu push, il faudra lire tout le nouveau code qui a été poussé pour trouver ce qui a cassé le test.
Quel est mon bilan ?
Aujourd’hui je n’en suis qu’au début de mon utilisation du TDD et je suis convaincu qu’il me reste énormément à apprendre. Je sais entre autres, que mes tests sont parfois trop liés à mes implémentations (c’est à dire que lorsque l’implémentation change mais pas le besoin client, il faut parfois modifier mes tests alors que ça ne devrait pas être le cas).
Le coût d’entrée pour le TDD a été élevé mais en le faisant par étape (dans des cas simples en Kata, puis sur quelques cas où on se sent à l’aise et enfin plus régulièrement) j’ai eu la sensation de progresser petit à petit sans avoir d’énormes difficultés.
J’ai vraiment adopté le TDD: ça ne fait pas longtemps que j’ai remarqué ça mais j’ai beaucoup de mal à coder autrement (lors de sessions de pair programming par exemple). En fait, à force d’être habitué à avoir des feedback toutes les quelques secondes, avoir plusieurs minutes sans savoir si je vais dans la bonne direction ou si j’ai rien cassé provoque une sorte de malaise “^^.
A mon sens, il y a vraiment eu un avant et un après concernant mon utilisation du TDD et même si ce n’est qu’une méthodologie qui ne va pas régler magiquement tous les problèmes qu’on rencontre, je trouve que c’est un outil qui me permet de faire du travail de meilleur qualité tout en gagnant en sérénité.
Encore une fois, j’ai encore beaucoup à apprendre et je ferais peut-être un autre article dans quelques années pour voir mon évolution dans cette pratique 🙂 Si vous avez des feedbacks à faire sur le TDD, n’hésitez pas à le faire en commentaire !