Article écrit par Gaëtan Dejaegere
Véritable ascenseur émotionnel pour tout développeur, le faisant passer successivement du déni à la frustration, de l’incrédulité à la résignation, puis de l’espoir au soulagement, le débogage est un art à part entière empli d’enseignements qui nécessite une attitude et des compétences spécifiques. À travers cette série d’articles, nous découvrirons méthodes, techniques et astuces pour transformer ce moment en plaisir non dissimulé. Cette première partie s’attachera à décrire les différentes étapes clés d’une résolution effective de bug.
Reproduire l’erreur
Pour commencer, il est impératif de ne pas foncer tête baissée dans la résolution du problème. Ne touchez pas à une ligne de code et acharnez-vous à reproduire l’erreur ! Cette étape permettra de vous mettre dans des conditions de travail idéales et vous fera, au final, gagner sérénité et temps. Celui d’un développeur est précieux, vous devez avant tout vous assurer de la réelle existence du problème et avoir la certitude de l’avoir au final corrigé. Quoi de plus frustrant que de revoir des semaines plus tard le même bug refaire surface !
La résolution d’un bug débute généralement par l’analyse du rapport fait par la ou les personnes en charge de la recette fonctionnelle de votre application. C’est-à-dire le plus fréquemment… le client. Rarement un profil technique, souvent dépourvu du vocabulaire associé, vous aurez pris soin de lui fournir un processus (voire un template) de remontée de bug le plus dirigé possible. Vous éviterez alors le simple « ça ne marche pas ». Gardez à l’esprit que ce document doit vous fournir les informations essentielles à la reproduction du problème. En voici les dix commandements :
- Les faits, uniquement tu énonceras (« je ne suis pas identifié, et j’accède à telle information privée »)
- Les spéculations, tu éviteras (« je pense que cela vient d’un problème de… »)
- Aux spécifications fonctionnelles, tu feras référence
- Ton environnement (OS, navigateur, profil d’utilisateur), avec précision tu décriras
- Les différentes étapes nécessaires à la reproduction du problème, tu listeras
- Le log d’erreur, véritable Graal, si possible tu fourniras
- Que l’erreur n’a pas déjà été rapportée, tu vérifieras
- Ton écran, pour décrire un problème graphique tu captureras
- Le qualificatif « intermittent », autant que faire se peut tu banniras :/
- Constructif, tu resteras (un développeur est très, très susceptible)
Une fois analysé et compris, faites en sorte de reproduire le bug au plus proche de vous. Vous n’aurez pas accès au même confort d’investigation en local avec l’ensemble de vos outils de prédilection, au sein d’un environnement de test, voire pire en production (oups). Simplifiez-vous la vie en mettant en place en un scénario de reproduction le plus court possible. Idéalement, vous écrirez ou corrigerez à cet instant le test unitaire associé, afin de vous prémunir contre une éventuelle régression future et de fluidifier le travail de diagnostic.
Il arrive malheureusement qu’un bug soit difficilement reproductible. La tentation de classer l’affaire sans suite se montre alors plus grande que jamais ! Résistez et trouvez-en la raison :
- le rapport de bug est mal renseigné
- Les données que vous manipulez ne vous permettent pas de reproduire l’erreur
- La résolution d’un autre problème a corrigé le bug remonté
- Vous tentez de reproduire le bug sur un environnement trop différent de celui sur lequel le bug a été rencontré
- Vous êtes face à un Heisenbug… Bon courage
Poser un diagnostic
Une fois dans les conditions optimales, Vous passerez à la phase d’investigation. Tel un Columbo en puissance, il va falloir faire des hypothèses sur l’origine du problème et vérifier celles-ci pour cibler la section de code incriminée. Les bugs n’apparaissant pas encore par magie ou sous les ordres d’une IA malveillante, vous procéderez avec méthode :
Réduire au maximum la surface de recherche
- Vérifiez qu’un changement récent d’environnement n’est pas la cause du problème (montée de version d’une dépendance, modification du schéma de base de données, etc.)
- Répétez votre scénario de reproduction en remontant l’historique de votre VCS jusqu’à trouver le commit et donc les modifications qui ont introduit le bug
- Mockez les parties de votre application non impliquées afin de limiter les interférences
- Blackboxez le code des librairies tierces
- Communiquez avec vos collègues : ils sont souvent de bon conseil et inspirants
Mettez en place des méthodes de recherche rigoureuses
- Vos expérimentations doivent avoir une fin en soi (améliorer votre compréhension du programme, confirmer ou infirmer une de vos hypothèses) ; on trouve rarement la source du problème par hasard
- Ne modifiez qu’une chose à la fois, condition sine qua non pour valider une hypothèse
- Gardez une trace de vos expérimentations afin de ne pas revenir sur des hypothèses déjà invalidées
- Gare aux certitudes, l’histoire des sciences a trop souffert des obstacles épistémologiques de ce cher Gaston Bachelard !
Apprenez à utiliser les outils à votre disposition.
IDE, console API, monitoring, breakpoints, blackboxing, debugging proxy, voici des outils plus ou moins puissants à votre disposition pour débusquer les fauteurs de troubles. Nous consacrerons un article complet à leur utilisation dans le cadre d’une application JavaScript dans la seconde partie de cette série.
Fixer
Bravo, vous avez identifié la source du problème ! Il est temps maintenant de corriger la section de code qui pose souci sans introduire de régression et dans le respect des normes de qualité en vigueur au sein de votre équipe. Faites attention à bien traiter la cause du problème et non ses symptômes. Dans les cas où le choix d’implémenter un quickfix est fait collectivement, il sera alors clairement identifiable et impérativement temporaire. Si cela se révèle être pertinent, refactorisez votre code. Enfin, aussi rigoureux et expérimenté que vous soyez, faites-vous relire !
Élargir la réflexion
Il est maintenant temps de tirer les conclusions des étapes précédentes. Comment ce bug a-t-il pu passer entre les mailles du filet ? Un problème similaire peut-il se produire ailleurs dans votre application ? Comment s’assurer de ne pas le voir réapparaître ? La documentation doit-elle être mise à jour ? Vous devez profiter de cette correction pour améliorer et questionner la qualité de votre codebase.