TDD est mort, longue vie TCR ?

Cela fait deux mois maintenant que Kent Beck a écrit son article sur TCR.
Pour résumer l’article, TCR est un acronyme de `test && commit || revert`. L’idée est d’avancer avec des petits pas maîtrisés et de revenir en arrière automatiquement au moindre dérapage. Cette pratique est contradictoire avec TDD qui impose une étape où un nouveau test doit ne pas passer. Ce qui est surprenant venant de la personne qui a inventé TDD !

La grande contrainte de TCR : le code doit toujours être vert

C’est la première chose qui saute aux yeux : si la commande `test && commit || revert` est lancée alors que le code ne compile pas ou qu’il ne passe pas les tests (code rouge), alors tous les changements sont immédiatement supprimés afin de retomber dans un état stable (code vert).

Cela semble contre-productif au départ et c’est exactement pour cette raison qu’il faut essayer (TDD aussi semble contre-productif à première vue). Après quelques heures d’essai (seul et à plusieurs), il apparaît que ce n’est pas contre-productif du tout et que c’est très fun.
Ce n’est pas contre-productif car TCR nous impose d’avancer à notre rythme. Tout le monde veut aller le plus vite possible, mais TCR vient nous mettre une limitation de vitesse en fonction de nos capacités du moment. Au moindre faux pas, TCR met le pied sur le frein un peu comme un régulateur de vitesse dans une voiture. Si le développeur est en forme et arrive à faire de grandes avancées dans son code, TCR ne l’empêchera pas, mais s’il est fatigué et/ou trop confiant, alors les changements seront annulés jusqu’à ce que le développeur fasse preuve d’humilité. Au final, on se retrouve à avancer à la vitesse maximale qui reste sûre pour la stabilité du code.
TCR est fun (et un peu frustrant) car on a l’impression de jouer au poker contre le code. Quand on lance la commande on peut s’entendre dire «je parie que ce code est vert ! Tapis !». Si on a raison, on gagne un commit, si on se trompe, on perd son code.

La grande force de TCR : le code est toujours vert

Le grand avantage de cette démarche est que le code est toujours dans un état stable et qu’il est commité (très) souvent. La conséquence est que le code est toujours intégrable. On peut donc pousser l’intégration continue à son paroxysme.
Il est par exemple imaginable de faire tourner un script du genre :

while(true){
    git pull --rebase && git push
}

Ainsi, au moindre changement commité, il est intégré et prêt à être partagé avec les autres membres de l’équipe.
Cela peut sembler extrême (comme l’Extreme Programming) mais imaginez une autre personne qui travaille sur le même morceau de code que vous sans que vous le sachiez. Si vous travaillez de manière «classique» vous vous en rendrez compte quand vous et elle aurez fini. Avec cette méthode, vous serez au courant au plus tôt :dès que les deux aurons fait passé leur premier test. Ce sera alors l’occasion de discuter avec elle voir de pairer !
Encore une fois, on gagne en productivité !

La grande faiblesse de TCR : le code est toujours vert

Du fait que le code soit toujours vert, il est impossible d’observer un test passer au rouge pour le faire passer au vert ensuite. Or il s’agit là d’une étape importante de TDD.
En effet, cette étape permet de valider :

  1. Que le test vérifie effectivement quelque chose
  2. Que le code ne fait pas déjà passer le test
  3. Que le message d’erreur est suffisamment explicite pour comprendre ce qui s’est mal passé

Le point 1 peut être mis de côté si nous partons du principe que cela est trivial, il suffit d’avoir un `assert` dans le test (spoiler alert, il est possible d’avoir un `assert` et de ne tester aucun code de production). Cependant, les points 2 et 3 ne peuvent être validés qu’en lançant le test ! Or, si nous faisons ça avec TCR, le test disparaitra suite au revert.
TCR semble donc incompatible avec TDD

Oui, mais…

Rien ne nous interdit de lancer la commande `test` sans le reste. Par exemple, quand on pense que le test doit être rouge, alors on ne lance que `test` sinon on lance `test && commit || revert`. Et voilà ! TDD et TCR sont parfaitement compatibles. Il suffit de ne pas être dogmatique sur la commande de TCR (qui est, pour rappel, juste une idée lancée il y a deux mois).
À partir de là, il est possible d’aller plus loin. Par exemple, à l’étape rouge, pourquoi ne pas lancer `test && revert`. Cela aura pour effet de forcer le test à être rouge et apporte les même bénéfices que TCR pour la phase vert (maîtrise de la vitesse et fun).
Allons encore plus loin ! Pourquoi ne pas lancer `test && revert || commit` ? Pour une raison simple : on se retrouve à commiter du test rouge. Or, pour rappel, nous avons un script qui fait de l’intégration en boucle. Nous allons donc partager du code rouge avec tous nos collègues !
Dans le cadre de TCR, cela aura pour effet de reverter tout changement qu’ils feraient. C’est idéal pour se faire des ennemis !
Cependant, si nous changeons notre script d’intégration continue en :

while(true){
    git pull --rebase && test && git push
}

Alors aucun risque de pousser du code rouge !
Cette piste me semble très prometteuse et c’est ce que j’explore à l’heure actuelle. Je partagerai mon expérience dans un prochain article. En attendant, je me fais écho de Kent Beck et vous encourage fortement à essayer TCR pour voir ce que ça pourrait changer pour vous.

Une réflexion sur “TDD est mort, longue vie TCR ?

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

%d blogueurs aiment cette page :