lundi 20 août 2012

TDD n'est pas tester !

Tu fais du TDD toi ?
Bah ouais, des fois j'écris mes tests en premier.
Et ton taux de couverture du code par les tests ?
Bah j'essaie d’atteindre les 80 %, y parait que c'est une bonne moyenne.
Souvent je rencontre des développeurs qui me parles du TDD comme cela.
Mais malheureusement il n'ont pas saisi ce qu'était le TDD, les objectifs qu'il permet d'atteindre, la façon de le mettre en œuvre.
Je vais essayer d'expliquer comment je vois et pratique le Test Driven Development, avec succès depuis quelques années.



BRISER LES MYTHES

Un des arguments de résistance à l'adoption du TDD est souvent que faire du TDD c'est trop long, qu'on a pas le temps, et que tester après avoir écrit est généralement plus simple, car le code de production est déjà écrit.
Cette vision est révélatrice de la méconnaissance, par de nombreux développeurs, de ce qu'est et n'est pas le TDD.

Le TDD est une pratique popularisée par l'eXtreme programming, parmi d'autres comme le pair programming, le refactoring etc...
L'acronyme signifie Test Driven Development ou Développement piloté par les Tests pour les non anglophones.

Brisons plusieurs mythe à son propos :
- le TDD ce n'est pas Test First, cela n'est qu'une partie de la méthode
- le TDD ne rend pas les développements plus long, c'est même le contraire
- le TDD ne rend pas plus rapide qu'à long terme, il rend plus rapide même à court terme
- le TDD n'a pas pour but de tester son code de production, cela n'est qu'un effet de bord de la méthode, si on peut dire, bien pratique pour le refactoring

LA REVELATION

Rentrons dans le vif du sujet. Le TDD parle de développement piloté par les tests, donc les tests y sont vu comme un outil de conception.
Première révélation : le TDD n'a pas pour but de tester son application mais de la concevoir, c'est une méthode de conception !

Mais par quel miracle les tests permettent-ils de concevoir son application ?

L'idée, comme dans toute méthode agile, est d'obtenir du feedback sur ce que l'on fait.
Concevoir, c'est faire des hypothèses. On peut avoir vu juste ou se tromper. Le test est là pour permettre d'avoir un feedback rapide sur nos hypothèses, et donc de limiter au maximum le fameux "effet tunel".
Mais pour que cela soit vraiment efficace, il faut suivre une routine, ce que décrit la méthode de Test Driven Development.

RED, GREEN, REFACTOR
  1. J'écris un test unitaire qui spécifie une micro-fonctionnalité de mon application (on parle de baby step) - cela ne doit pas dépasser un ordre de quelques minutes sinon cela indique que vous spécifiez trop gros. Le test doit échouer (red)
  2. J'écris le code strictement nécessaire à faire passer le test - et pas plus ! On évite au maximum d'induire une conception a priori, on essaie plutôt de faire émerger certains problèmes (par exemple la duplication de code) qu'on règle au besoin. Le test passe (green)
  3. Maintenant que mes tests sont au vert, je peux me permettre d'éventuellement nettoyer mon code (de production et de tests), d'éliminer la duplication etc... - refactor
EXPLICATION

L'objectif est de limiter le temps de feedback entre deux hypothèses de conception. On progresse pas à pas, on est itératif et incrémental. Plus on avance plus on en apprend sur le système qu'on conçoit, tout cela validé par les tests.
Il faut donc que le cycle red - green - refactor soit le plus court possible, de l'ordre de la dizaine de minutes.
En écrivant juste le code nécessaire à faire passer les tests, on s'assure que le code répond strictement aux spécifications que sont les tests.
Apparait ainsi tous les problèmes de conception que l'on peut régler a posteriori via le refactor, rendu rapide et sûr par la suite de tests produite en amont.
Par exemple, au lieu d'induire un conception qui exclue la duplication, on fait apparaitre celle-ci et il est ainsi aisée de la visualiser pour la faire disparaitre. C'est ainsi qu'on parle de conception émergente en TDD.

EN PRATIQUE

Bon Ok, il faut écrire un petit test, avancer pas à pas, mais comment je fais concrètement pour choisir le prochain tests à écrire et réellement guider mon développement par les tests ?
L'idée est que le prochain pas doit être petit et apporter une nouvelle fonctionalité. Cela est visible par le fait que le test échoue. Si vous écrivez un test qui passe directement au vert, effacer le, et trouver en un autre.

CONCLUSION

En conclusion, le TDD c'est :
  • Test First
  • baby step
  • red, green, refactor
  • KISS (keep it simple & stupid)
  • YAGNI (n'implémenter que le juste nécessaire spécifié par les tests)
Mais aussi SOLID, etc...

Pour bien pratiquer TDD, il faut se rappeller sans cesse pourquoi il est utile : concevoir, avoir des boucles de feedback régulières et fréquentes sur cette conception, faire émerger les mauvais pattern (duplication, dépendances entre classes, ...) pour les corriger ensuite.

Dans un prochain article je vous proposerais une démonstration pratique de la méthode Test Driven Development, explicitant les stratégies pour écrire le prochain test et illustrant les principes de la méthode TDD.

tdd - wikipedia
tdd le piège à éviter
eXtreme programming

1 commentaire:

  1. Bonjour,

    Effectivement ça rejoint bien cet article en anglais: bit.ly/W1Y46S

    D'ailleurs je suis même peut être plus en phase avec ton article, car celui en anglais parle de tester également les cas limites (null, type non attendu etc...), ce avec quoi je ne suis pas forcément d'accord, en tout cas dans le cadre du TDD.

    J'aime beaucoup les mythes que tu brises et la conclusion, c'est exactement ça de mon point de vue!

    RépondreSupprimer