Bonjour à toutes et à tous et bienvenue dans ce nouvel épisode du podcast PunkinDev.
Et oui,
vous avez vu le titre.
TDD c'est Overkill.
Limite,
ça sert quasiment à rien.
Et vous devez vous dire,
mais il fait quoi PunkinDev,
il a pété les plombs à dire des trucs pareils ?
Alors si le crafteur qui est en toi s'offusque de ça,
respire,
ça va bien se passer.
Si à l'inverse tu détestes tes dédés,
respire,
ça va peut-être pas si bien se passer.
Reprenons déjà les bases.
TDD c'est quoi ?
Alors TDD j'en ai parlé il y a longtemps dans le podcast,
mais on va quand même repartir du début.
Comme j'ai très bien appris ma leçon,
parce que je suis un très bon élève,
je sais que TDD c'est Red Green Refactor.
D'abord j'écris un test qui plante,
la phase rouge,
red,
puis je code l'impleme pour faire en sorte que le test passe,
ça c'est la phase verte.
Et enfin j'ai tout loisir d'améliorer mon code,
de faire du rifacto.
Certains appellent ça.
ça la Fuzz Blue.
Mais je peux faire ce refacto parce que ma suite de tests m'assure que je ne vais rien casser.
Saurez-vous noter la petite subtilité qui s'est glissée dans cette définition ?
Sur le passage au vert,
justement.
Cette définition précise que l'impleme doit être en fait la plus triviale possible.
On doit produire le code minimal qui permet de faire passer le test du rouge au vert.
Et pour moi c'est cette petite subtilité qui change beaucoup de choses,
qui change en fait un petit peu tout.
C'est cet élément qui introduit,
qui induit la notion de baby steps,
d'incréments aussi petits que possible.
Et sans ça,
on ne va pas pouvoir laisser les tests piloter notre implême,
comme TDD nous incite à le faire.
TDD,
pour mémoire,
c'est Test Driven Development.
C'est du développement piloté par les tests.
Pour être très honnête,
c'est cette phase qui,
pour moi,
est la plus difficile à apprendre de TDD.
On peut facilement apprendre à coder des tests avant de coder des implêmes,
sans vraiment faire du TDD.
On peut donc finir avec un simili-TDD que certaines personnes appellent du test-first.
Mais faire ça en ayant déjà une forte idée de l'impleme qu'on va produire après.
Et au final un peu biaiser l'écriture de nos tests pour parvenir à cet implème.
Pour certaines personnes,
effectivement là on n'est pas sur du vrai TDD comme il faut le faire normalement,
sinon on n'est pas des bons devs.
Mais en vrai...
Est-ce que c'est grave de ne pas faire du pur TDD by the book comme c'est précisément défini ?
Pour les puristes qui s'étripent à savoir s'il faut faire du TDD en London ou en Chicago School,
c'est probablement un odieux crime de lèse-majesté.
Mais en vrai,
non,
je ne suis pas d'accord.
Ça n'a rien de grave.
C'est pas grave de ne pas faire du TDD parfaitement.
Qu'est-ce qui est important ?
Qu'est-ce qui compte vraiment ?
Faire style,
qu'on maîtrise à fond la pratique,
plus ou moins à la mode,
ou alors toujours essayer de délivrer le max de valeur le plus sereinement possible ?
Pour la valeur,
le débat est plus compliqué.
Mais pour le côté sereinement,
on va causer.
Pourquoi on écrit des tests au fait ?
Pour moi,
écrire des tests,
c'est juste pour se simplifier la vie.
Pour faire en sorte de savoir que notre code fonctionne.
Et j'appuie sur le savoir.
Savoir plutôt qu'espérer.
Écrire des tests automatisés,
c'est sortir du edit and pray.
Et basculer dans un monde factuel et serein.
Et en vrai,
rien qu'arriver à ce niveau-là,
c'est déjà hyper coûteux.
Il y a des applis legacy où il va falloir faire un paquet de travail de rifacto.
d'archives pour pouvoir poser le moindre TU.
Donc en soi,
rien que le fait d'avoir des tests automatisés,
ça peut des fois constituer un pas énorme.
Oups.
J'ai dit TU juste avant.
Allez,
une petite parenthèse vite fait.
C'est quoi un TU ?
Un TU,
c'est un test unitaire.
Merci Captain Obvious.
Oui,
donc ça doit tester une unité.
On avance.
Alors en réalité,
toute la problématique porte sur le choix de cette unité.
Il y a encore des gens qui font débat là-dessus.
Pourtant,
dans le cercle des initiés,
tout ça,
blabla,
il n'y a plus trop de débat là-dessus.
Mais dans un apprentissage,
ça peut évoluer.
Quand on écrit nos premiers tests,
on se dit que l'unité...
c'est la fonction,
la méthode,
ou au pire une classe.
Je pense vraiment que la plupart des devs ont commencé par là.
Et généralement,
on a rapidement des soucis avec plein de tests sur une même fonction.
Dès qu'on touche à la fonction,
ça casse des tests,
et souvent on désactive les tests et on abandonne jusqu'à croiser la bonne personne,
le bon bouquin,
qui va nous expliquer ce qu'on a loupé.
Pour moi l'unité à prendre dans un test unitaire c'est une unité métier,
fonctionnelle.
Dans un TU on va valider une petite unité de comportement métier qui pourra peut-être ne tenir que dans une fonction mais peut-être et probablement plus.
L'important c'est que la fonctionnalité reste valide et ce quelles que soient les modifications opérées sur les impléments.
Fermons la parenthèse sur les TU.
Donc imaginons,
on arrive à écrire des tests unitaires,
automatisés.
Ça fait le taf,
non ?
On a des comportements validés par des tests,
donc on peut sereinement passer d'une itération à l'autre sans crainte de tout péter.
Alors sur le papier,
ouais,
ça semble parfait.
Sauf qu'en vrai,
tout seul,
d'écrire des tests comme ça,
ça suffit pas.
Pourquoi est-ce que vous pensez qu'on se casse la tête à écrire des tests avant de coder un impléme ?
Je vous spoil déjà la fin.
Mais est-ce que vous avez entendu parler de ce qu'on appelle le biais de confirmation ?
Ça aussi j'en ai causé dans un très vieil épisode.
Mais on va refaire rapidement l'expérience.
Imaginez je vous donne une suite de nombres,
je sais pas moi,
3,
6,
9,
et je vous demande de me proposer des nouveaux nombres pour tenter de cerner quelles règles s'appliquent à cette suite.
Je peux vous laisser une seconde pour y penser.
Mais quand je dis 3,
6,
9,
je pense que la plupart d'entre vous ont pensé à 12,
15,
18.
pour vérifier qu'on était bien sur une suite des multiples de 3.
Vous avez eu une idée,
et vous avez cherché à la confirmer.
Est-ce que c'est la meilleure façon de vérifier qu'on ne se trompe pas ?
Eh ben non,
c'est même la pire.
Si vous êtes convaincu qu'on a des multiples de 3,
la meilleure façon de savoir qu'on ne se trompe pas,
ça consiste à échouer,
à trouver des contre-exemples en tentant.
je sais pas,
10,
658,
pi,
racine de 5,
moins 12.
Et si le moindre de ces nombres vient à valider la règle,
et bien toute la belle croyance qu'on s'était construite avant,
ça va s'effondrer.
Et ça sera d'autant plus douloureux que vous aurez investi plein d'énergie pour aller dans ce sens-là.
Pour nos tests,
c'est pareil.
Si vous avez écrit une implème et fait en sorte que le test passe au vert,
a priori,
vous allez y arriver.
Le test va passer vert assez rapidement.
Mais qu'est-ce qui prouve que c'est bien le comportement que vous voulez tester qui fait passer le test au vert et pas un artefact étrange ?
Ça,
ça arrive.
Le biais de confirmation,
tout le monde l'a.
Même quand on sait qu'il existe,
qu'on sait qu'on l'a,
eh ben on l'a toujours.
Il n'y a pas vraiment de médicament.
Sauf,
on a un outil formidable dans le dev qui nous permet de contrecarrer ce biais de confirmation.
C'est de disposer d'un test en échec et de pouvoir constater ce qu'il fait passer au vert.
Et ça,
c'est une assurance que c'est bien le bout de code qu'on a produit qui permet de faire passer le test au vert et rien d'autre.
Donc si je reprends encore une fois,
avec ces deux éléments,
des TU bien découplés,
des tests écrits avant,
on pourrait s'arrêter là qu'on serait quand même vachement tranquille.
On rajoute un peu de rifacto pour l'hygiène,
et nous voilà avec un simili-TDD qui fait énormément de bien à nos applis.
Donc on aurait,
sans faire vraiment du TDD,
une espèce de panacée du développement logiciel ?
Là aussi,
il y a débat,
mais en un sens,
moi j'ai envie de dire,
ouais,
quasiment.
Et c'est pour ça que je postule que TDD,
c'est overkill.
Aujourd'hui,
si on regarde ce qui se fait en moyenne dans notre industrie,
s'arrêter à ce stade,
ça permet selon moi d'être déjà dans le haut du panier en termes de fiabilité et de sérénité de dev.
Sauf qu'on a un autre biais,
c'est qu'on n'aime pas s'arrêter de progresser.
Et on se dit que ça serait peut-être mieux de faire du vrai TDD.
Si vous vous souvenez ce que je disais au début de l'épisode,
ce qui manque à ce stade en fait c'est la notion de baby steps,
et surtout quelque part de lâcher prise.
Il faut se connaître,
on est formé et conditionné à penser en termes de solutions,
d'implémentation.
Donc quand un problème à résoudre arrive,
on va forcément avoir des idées d'implème.
Forcément.
La force de TDD,
quand on arrive à le faire un petit peu by the book,
de manière très rigoureuse,
c'est justement de ne pas se laisser polluer par ses idées,
et de laisser les tests nous amener à une implême à laquelle on n'aurait pas forcément pensé avant.
Mon spoiler final,
c'est que c'est dur.
C'est bigrement difficile,
et si j'étais moins poli,
je dirais que c'est dur sa race.
J'ai tendance à considérer qu'à prendre les étapes jusqu'à test first,
c'est 80 à 90% du boulot.
Sauf que les 10-20 derniers pourcents,
ils vont coûter 10 fois plus d'énergie que le reste pour les intégrer dans des automatismes quotidiens.
J'irai même plus loin avec un poste de travail.
Postulat selon lequel on ne peut pas se débarrasser seul de cette propension à faire notre design en amont.
La meilleure solution que j'aurais aujourd'hui à proposer pour pallier à ça,
le pair et l'ensemble programming.
Il existe même des contraintes de kata particulièrement efficaces pour apprendre ça.
Je pense au ping-pong per programming.
Une personne code le premier test,
donne le clavier à la deuxième personne,
qui fait l'implème,
puis code le test suivant,
et qui repasse le clavier à l'autre.
Et on fait un ping-pong comme ça.
Avec cette approche,
c'est impossible de s'accrocher à une implème prévue avant.
On n'aura que l'implème poussée par les tests.
Et si vous êtes d'humeur taquine,
refaites l'exercice,
mais en mode silencieux,
sans explication orale,
juste avec des tests.
des tests et du code,
c'est redoutable.
Mais c'est pas facile.
Je l'ai fait récemment et moi j'aime beaucoup.
J'aime beaucoup ce genre de difficultés.
Bon,
vous l'aurez compris,
mon but n'était pas tant de bicher sur TDD que de rappeler que c'est sincèrement difficile et que c'est ok.
C'est pas un problème de se mettre des objectifs intermédiaires,
raisonnables,
en attendant de progresser plus.
Quant au puriste du gna gna gna,
la London School,
la Chicago machin,
arrêtez de faire fuir les noobs avec vos querelles de paroisses totalement stériles.
Laissez les gens apprendre à coder des TU,
à les automatiser,
et ensuite à les coder avant,
et déjà.
ce sera ok,
encouragez-les,
faites-les travailler et vraiment,
c'est cool.
C'est donc sur cette note positive qu'il me reste à vous souhaiter une excellente semaine.
A la prochaine pour un nouvel épisode et d'ici là,
geekez bien et codez bien.
PAS SAUTÉ !
Adieu,
respectos !
On est qu'en 2016 !
Il y a ensuite un problème !
C'est ça !