Lorsque l'on s'intéresse au TDD (Test Driven Development), une question qui se pose est celle du temps supplémentaire qu'implique l'écriture des tests. C'est d'ailleurs l'une des principales craintes exprimées lorsque j'en explique les principes : « mais je vais perdre du temps ! »

Face à.ce temps supplémentaire à l'écriture, il est légitime de s'assurer une compensation par un gain, généralement sous forme d'un « gain de productivité ». Cette mesure est complexe. Comment mettre en place un protocole qui sortirait les différences entre plusieurs équipes, et sur quelles métriques ?

En toute rigueur, il faudrait deux équipes composées des mêmes personnes, ou au pire des mêmes profiles. Puis les faire travailler sur le même projet avec les mêmes objectifs. Si jamais ce protocole est mis en place, les logiciels risquent de diverger et de répondre aux objectifs de manières différentes, il faudrait donc aussi mesurer cette divergence.

Ensuite, quoi mesurer ? Par ordre de difficulté croissante de mesure, on peut penser à : la vélocité, le nombres de défauts du logiciel, la capacité du programme à évoluer.

Récemment, on m'a donné une référence sur une étude menée (pdf). Ce sont deux bonnes surprises. La première est que, tout le monde n'ayant pas forcément les moyens de faire ce genre d'études, que cette étude existe. La seconde, c'est que les résultats de l'étude sont plutôt positifs quant à l'intérêt du TDD. Cependant, l'article lui même avoue que le protocole n'est pas complètement sans défauts. Au final, le côté positif est surtout que le gain évalué en nombre de défauts est tellement énorme que cela donne envie de dire que même avec des erreurs de mesure, il y a de la marge.

Ça me laisse quand même toujours sur ma faim.

Et si on se trompait de chiffres ?

La sensation désagréable éprouvée par les débutants et réfractaires au TDD est qu'ils vont être moins productifs. C'est-à-dire livrer moins pour un temps donné. Les pratiquants du TDD ont beau leur promettre qu'au final, ils y gagnent, sans chiffre, sans preuve, ce n'est pas facile à accepter.

En y réfléchissant un peu, cela signifierait que le temps supplémentaire d'écriture des tests est significatif par rapport au développement de la fonctionnalité sans ces tests. Or, la rédaction d'un programme représente une partie minoritaire dans la suite des étapes de développement. La définition du besoin, le design, l'étude de faisabilité, la compréhension de l'existant, la lecture de documentation, le contournement des bugs du système sur lequel on de base. Puis plus loin la livraison, le déploiement, le debug. Toutes ces phases se retrouvent, d'une manières plus ou moins visible, dans chaque développement.

Et pour le coup, mesurer le temps d'écriture de nouveau code par rapport au reste est facilement mesurable. Et cela se trouve un peu mieux dans la littérature.

Une expérience récente

J'ai pensé à cette minorité du temps d'écriture lors d'un développement récent. Pour faire court : dans un application existante, je devais ajouter un appel REST à un service, décoder la réponse et injecter le résultat dans l'application locale. L'affaire d'une bonne heure, le temps de comprendre l'existant et l'API REST.

J'ai bien entendu utilisé le TDD, ce qui me permettait d'être certain, au fur et à mesure du développement, que ce que je faisais était bien ce que j'avais en tête. Sans le TDD, ça m'aurait sûrement pris 20 à 30 minutes.

Au bout d'une heure et demi, j'ai mon système en place qui fonctionne avec un système de Mock. Je l'essaie donc avec un appel réel au service. Impossible d'accéder à l'API REST. Alors que si je fais la même requête avec un CURL, ça passe. Je tourne, je fouille dans la documentation (tout doit marcher comme je fais), je vais voir sur Stack Overflow, qui fidèle à lui-même ne m'aide pas vraiment... Je fini par dégainer Wireshark, à comparer les requêtes, m’apercevoir que la requête envoyée par l'application est incomplète et du coup corriger cette partie.

Ma requête passe. Ainsi qu'une autre bonne heure (le temps passe vite...).

Mais pour accéder à l'API REST, je dois avoir un token fourni par une autre application locale. Jusqu'à ce moment là, j'avais simulé avec un token que j'avais pris manuellement. J'appelle donc à présent la fonction qui doit me donner un token valide. J'obtiens une erreur. A priori, j'ai une version trop vieille de « quelque chose ». Je cherche, je fouille, je contacte des spécialistes de cette partie, qui me disent de mettre à jour une bibliothèque, que je mets à jour. Toujours la même erreur.

Et ainsi de suite.

Deux choses dans cette expérience. La première, c'est que la proportion de temps supplémentaire avec du TDD est ridicule par rapport au temps total d'implémentation de la fonctionnalité, tout en m'assurant à chaque étape que la partie que j'ai ajoutée est intacte. La seconde, c'est que si les autres parties avaient eu des tests, j'aurais (peut-être) pu insérer dedans les miens pour valider ou invalider ce qui se passait mal, et résoudre plus rapidement les erreurs.

Alors ce coût ?

Ce coût existe, et je parlerai peut-être dans d'autres articles des gaines que l'on peut attendre du TDD. En attendant, s'y mettre ne rallongera pas beaucoup vos développements, ceux-ci sont constitués d'assez peu de phases de « code » pur.