Le demi-cercle (épisode 2 -- Voir / Avancer)
(Résumé des épisodes précédents : Et si c'était le moment où on pose son ouvrage et on réfléchit ? Si c'était le moment où l'on commence à changer un peu la manière dont on fait les choses ?)
Prenons ce bug. Tu viens d'identifier l'origine du problème, et aussitôt tu t'es figuré la solution. En un clin d'œil. Tu ouvres le code, tu fais la modification qui va bien. Tu relances l'assemblage. Dans dix minutes, l'application sera livrable en recette. Il faudra remettre en place des données de test pour le compte du client. Il faudra attendre que le client fasse ses tests, et donne son feu vert pour le passage en production.
Tu réfléchis. Tu fais les questions et les réponses. - Et si ça ne devait pas marcher ? - Ça marche; j'en suis sûr. - Et si ça ne devait pas marcher ? - Ça ne se serait pas de notre fait. - Si ça ne devait pas marcher, combien de temps faudrait-il pour en être informé ? - Plusieurs heures, voire plusieurs jours.
Tu réfléchis encore. - De deux choses l'une : soit le programme est maintenant corrigé, soit il comporte (au moins) un nouveau défaut. - S'il est corrigé, alors nous faisons toutes ces démarches de test pour rien. - S'il ne l'est pas, alors il vaut mieux attendre d'en être certain avant de réagir.
Tu marches à tâtons dans l'obscurité. L'incertitude. Ce qui est certain, c'est que la pièce est assez vaste — on dirait qu'elle résonne. Et aussi qu'elle est particulièrement encombrée, par un tas de trucs indéfinis, non identifiés, un fatras. Mais tu ne peux rien voir. Tu peux seulement tenter d'avancer, et buter dans l'obstacle qui se trouve là. Ce jeu — que tu adorais à quinze ans mais qui commence à te fatiguer maintenant que tu en as presque trente — possède une règle bien identifiée par tous les joueurs :
"voir" = buter dans un obstacle.
Dans cette situation, quelle sera ton approche préférée ? Est-ce que tu ralentis et tends les mains pour détecter les obstacles, ou bien est-ce que tu t'engages prestement et traverse la pièce avec aplomb ? D'autres se mettraient tout de suite à quatre pattes, pour ne pas risquer une chute. Petits joueurs. Marcher à quatre pattes, c'est s'avouer vaincu d'avance.
Tu marches à l'aveugle, mais debout. Tu prétends pouvoir sortir de la pièce en un seul trajet. Tu affirmes : « C'était le dernier défaut ! » Tu dis : « Il reste juste ce tout petit problème à corriger et on est bons. » Mais pas une seule de toutes les parties précédentes que tu as jouées ne s'est déroulée sans que tu ne rencontres, en le percutant, un obstacle. Et à chaque fois, tu t'es cassé la figure, tu as ramassé et réarrangé à la hâte les trucs en questions, tu t'es figuré que ça devait vaguement former un bloc, une pile, ou bien au moins un tas, et tu t'es relevé. Voilà. Ça devrait faire le job. Tu aimerais bien rentrer chez toi maintenant. Tu te dis : "demain il fera jour". Mais demain quand tu reviendras dans la pièce, elle sera tout aussi obscure. Et à nouveau, peut-être, tu buteras dans des nouveaux obstacles, de forme et de taille inconnues.
Bombes logiques. À mesure que tu corriges des défauts, tu en sèmes de nouveaux.
Ce que tu pourrais faire de différent ?
Tu ne peux certes pas allumer dans la pièce. Si tu pouvais allumer, cela résoudrait une bonne partie du problème, évidemment.
Tu rêves qu'on allume dans la pièce, et dans ta tête tu entends comme une foule soudain satisfaite qui soupire : "Aaaaah!", et tu regardes :
Le premier obstacle dans lequel tu butais systématiquement n'était pas bien rangé. Une fois placé debout près de ce pilier, cet obstacle ne gênerait plus du tout, en fait.
Tu vois clairement maintenant certains obstacles que tu croyais insurmontables, inéluctables : tu réalises qu'on peut les faire disparaître en deux-temps, trois mouvements.
Cet obstacle dont tu te disais : "ça doit être le dernier", se trouve comme étalé sur toute la surface de la pièce, tu peux à peine compter les occurrences, il n'y en a pas "juste un dernier", il en reste des douzaines.
Et dans cette lumière éclatante et cette netteté nouvelle, tu es sur le point de réaliser une deuxième règle que beaucoup moins de joueurs connaissent :
"avancer" = créer de nouveaux obstacles
Mais tu ne peux pas vraiment formuler cette règle numéro 2 parce que tu n'as ni les moyens (il faudrait savoir comment) ni le temps (il faudrait des mois) de rétablir la lumière dans ce projet aveugle.
Trêve de rêveries.
Que faire ? Une pause.
Tu vas au coin cuisine/café/baby et tu te prépares une soupe Ramen. Tu reviens et tu la manges devant ton écran, qui déplace en silence des couleurs fauves autour d'une horloge qui dit : 20h45. Avec un petit jus de mangue, et un cookie Chinois. Tu ouvres le cookie Chinois, tu déplies le papier.
On apprend tous de nos erreurs… Vous allez beaucoup apprendre aujourd'hui.
Très drôle. Tu repenses à la blague de Jérémie hier midi. Jérémie — qui fait montre d'un esprit moqueur et d'un vif scepticisme à l'égard de tout ce qui est méthodologie — ouvre un cookie Chinois et lit d'un ton docte : "Chaque ligne de code est justifiée par un test qui ne passait pas". Ce qui a fait rire toute la tablée, même ceux qui entendaient ce truc pour la première fois.
Cette blague. Chaque ligne de code est justifiée par un test qui ne passait pas. Et puis quoi d'autre ?
Tu déverrouilles ton écran. Pourquoi pas ? Tu peux décider maintenant, comme une sorte de principe de survie en milieu obscur, que les obstacles rencontrés ne se remettront pas dans ton chemin.
Tu reviens en arrière; tu reprends la version bugguée du programme; tu crées un module de test; tu écris un test qui ne passera pas; il ne passera pas parce qu'il y a cette erreur -- ce bug. Écrire le test te prend du temps. Le code ne s'y prête pas, ne se soumet pas facilement à des tests de cette sorte. C'est parce que le test vise une partie du code qu'il faudrait exécuter indépendamment de tout le reste. C'est d'autant plus idiot que cette partie est toute petite. Deux lignes.
Le code est couplé à ses dépendances extérieures. Tu mets l'effort que requiert la création de ce test en regard de l'insignifiance de la ligne de code qu'il permet de tester. Tout ça pour ça. La montagne accouche d'une souris. Frustration.
Tu es arrêté dans tes pensées par le vrombissement du téléphone. C'est Stéphanie. - J'ai eu ton message. J'ai dîné. Tu en as pour longtemps ? - Plus tellement. Je suis crevé. Ça va ? - J'essaie de réparer mon vélo. C'est le dérailleur. - Oh! - C'est pénible. J'ai essayé de le régler mais je ne peux pas manœuvrer le dérailleur sans pédaler et rouler. Et quand je roule, je ne peux pas regarder le dérailleur de près. En plus il fait nuit, et la lumière de la cour est trop faible. - Ah. - Donc je retourne le vélo, je le mets sur sa selle et j'actionne les pédales. Mais dans ce cas là, la chaîne ne s'enroule pas de la même façon sur le dérailleur parce que le vélo est dans l'autre sens. - … - Et toi comment ça va ? - Pareil. - Tu rentres à quelle heure ? - Je pars dans 10 minutes.
Tu te dis : « À quoi bon, c'est impossible ». Mais réfléchis. Le délai qu'il te faudrait pour découpler un peu ce code et poser ce test, tu vas le passer à attendre que le client fasse ses tests ?
Tout en insérant d'autres bombes logiques dans le programme ?
Tu reprends l'idée. Tu casses les dépendances. C'est assez moche. Le code semble encore un peu plus baroque qu'il ne l'était avant ce test. Tu arrives tant bien que mal à isoler le code incriminé. Ce n'est pas spectaculaire, mais au moins ton test s'exécute sans faire appel à la base de données.
Il est rouge. Tu corriges le bug. Le test passe au vert.
Tu as peut-être encore le temps d'écrire un autre test, du coup. Cette partie du code est totalement (dans l'obscurité) dépourvue de tests. Pour cette partie du code, tu ne sais même pas ce qu'il faudrait que le test affirme. Tu exécutes le test, et le résultat te dit ce que fait effectivement le code. Tu colles ce résultat dans le test, tout en n'étant pas sûr que ce soit la vérité. Tu te dis qu'en tout état de cause, tu as déterminé ce que fait le code, et que tu pourras toujours t'appuyer sur ce test pour poser des questions à la responsable d'application. Ce sera toujours plus fiable que de lancer des hypothèses dans le noir et se casser la figure ensuite.
Tu décides pour un temps de garder ce principe, d'écrire un test pour chaque nouvel élément de fonctionnalité que tu voudras créer, ou modifier.
C'est comme si à chaque fois que tu dois explorer la pièce, tu pouvais poser à l'endroit où tu te trouves, une lumière, certes pas très puissante, mais qui, tout le temps que ce projet durera, ne s'éteindra plus.
Tu verrouilles ton poste, et tu rentres.