Être développeur signifie que plus de la moitié du temps, vous devez être un débogueur, parfois pour votre propre code, et à d'autres moments pour aider vos pairs dans la revue de code ou en cas de programmation en binôme. Bien qu'il s'agisse d'une compétence nécessaire pour les développeurs, le débogage n'est enseigné à personne à aucun moment de sa carrière, ce qui laisse penser que c'est très difficile.
Le débogage semble difficile, non pas à cause de sa mécanique, mais parce qu'il est difficile de comprendre par où commencer en tant que novice. Sans aucun doute, c'est un art qui peut être acquis en créant et en révisant de plus en plus de code au fil du temps, mais l'intuition peut être développée tôt avec quelques recommandations dont nous parlerons aujourd'hui dans cet article.
Commençons.
Reproduire le problème
Le pire scénario lors du débogage d'un problème est lorsque le bogue ne peut pas être reproduit de manière fiable. Cela peut se produire en raison de plusieurs facteurs tels que des conditions de concurrence, des systèmes externes ou des problèmes environnementaux qui entraînent différents modèles de comportement sur les systèmes déployés ou les boîtiers de développement.
Cela revient à la fois au testeur et au développeur que plus vous pouvez être précis dans la manière de reproduire le bogue, mieux c'est. De plus, une fois que vous avez trouvé le problème et un moyen de le démontrer, assurez-vous de mettre tous les détails sur sa reproduction ainsi que sur sa compréhension et sa résolution, sur un système de suivi des bogues. Cela vous aidera non seulement à vérifier le correctif une fois implémenté, mais aidera également les autres développeurs à comprendre la cause et la solution du bogue.
Voici quelques conseils simples à suivre lors de la description des étapes pour reproduire un problème :
- Essayez d'être précis, car plus vous mentionnez de probabilités, plus de pistes d'investigation s'ouvrent.
- Dans le cas où une entrée est requise, incluez toujours des exemples ou des exemples de valeurs. Mentionnez également les contraintes ou les règles spécifiées pour l'entrée utilisateur car cela pourrait être une cause probable du problème, ce qui mérite d'être vérifié.
- Spécifiez toujours les détails de l'environnement - système d'exploitation, type de navigateur et version du navigateur. Cela pourrait être particulièrement le cas pour les applications Web où les différents navigateurs peuvent représenter des comportements différents.
- Incluez les rapports de plantage pertinents, les journaux, les captures d'écran annotées, etc. pour expliquer correctement la différence entre la façon dont vous vous attendez à ce que l'application se comporte et la façon dont elle se comporte réellement, ne laissant aucune chance de malentendu au débogueur.
Convertir le problème en un test automatisé
Cette étape n'est pas toujours possible ; et parfois c'est possible mais pas pratique ou vraiment nécessaire, cependant, il peut y avoir des cas où cela vaut la peine d'être mis en œuvre. Le test automatisé, dans ce contexte, peut être tout ce que votre cas d'utilisation de développement utilise déjà pour les tests, comme un test unitaire ou un test d'intégration. Dans la mesure du possible, les tests unitaires sont un excellent choix car ils sont conçus pour être exécutés souvent, vous saurez donc si le problème revient bientôt.
Vous pouvez vous retrouver à écrire de nombreux tests unitaires qui réussiraient tout en essayant d'identifier la source du problème. Vous pouvez parfois vous retrouver à écrire des tests unitaires qui n'ont aucun sens en dehors de la situation actuelle, mais même ainsi, il n'y a pas de mal à avoir un test qui pourrait vous aider à identifier la source du problème. Ce n'est pas parce que ce n'est pas le problème actuel qu'il n'en trouvera pas un plus tard - et cela sert également de documentation supplémentaire sur la façon dont le code doit se comporter. Les tests unitaires de travail sont souvent une excellente approche pour déterminer quelle couche à l'intérieur d'un système génère le problème.
Refactorisez vos tests unitaires avec la même vigueur que vous le feriez pour votre code de production. Si vous avez un énorme test unitaire qui teste en fait un morceau de code important, essayez de le diviser en tests plus petits. Si vous êtes chanceux, vous découvrirez qu'un énorme test unitaire défaillant basé sur le problème d'origine peut être divisé en plusieurs tests de réussite et un seul test d'échec mineur.
Même si vous trouvez un problème dès le début et que vous pouvez le résoudre en une seule ligne, créez un test unitaire pour le valider dans la mesure du possible. Faire des erreurs lors de la correction du code est aussi simple que de le développer en premier lieu, et les principes du test en premier s'appliquent toujours.
Ne vous attendez pas à ce que les choses fonctionnent comme elles le devraient
Vous devez être un peu paranoïaque si vous déboguez un problème pour continuer car il est clair que quelque chose quelque part ne fonctionne pas comme prévu, sinon il n'y aura pas de problème. Vous devez être ouvert d'esprit quant à l'endroit où le problème peut se situer et naviguer avec votre connaissance du système impliqué.
L'objectif principal ici est de vous empêcher de prétendre que "le problème ne peut pas être là". Prouvez-le si vous ne le croyez pas. Si cela semble être, peu importe à quel point cela semble impossible, approfondissez-le davantage.
Soyez clair sur le but du code
Si le but d'un morceau de code n'est pas clair pour vous, qu'il soit ou non la cause du problème, prenez le temps de le comprendre. Vous pouvez toujours mettre des tests autour de lui et essayer de documenter ce qu'il fait. Si vous ne savez pas si le comportement est correct ou non, demandez de l'aide. Une fois que c'est clair, essayez de documenter tout ce que vous savez, que ce soit avec un test, une documentation XML ou un document externe.
Résoudre un problème à la fois
Si un morceau de code est exceptionnellement mauvais, vous pouvez finir par découvrir d'autres problèmes lors du débogage de l'original. Dans un tel cas, il est essentiel de décider quel problème doit être abordé en premier, puis de se concentrer uniquement sur ce problème.
Dans un monde parfait, vous résoudriez un problème, vérifieriez votre code dans le contrôle de version, puis corrigeriez le suivant, et ainsi de suite. Cela permet de déterminer facilement quels changements de code ont entraîné quels changements de comportement plus tard, ce qui est essentiel lorsqu'un correctif pour un problème s'avère en casser autre chose.
Faites en sorte que votre code vous aide à déboguer
Les journaux peuvent être incroyablement utiles pour le débogage. Ils peuvent vous donner des informations sur le terrain où les débogueurs pourraient ne pas être utiles. Cependant, la journalisation, tout comme le débogage, est également un art minutieux. Si vous ne le faites pas correctement, il se peut qu'il ne puisse pas vous aider de la meilleure façon possible. Ainsi, chaque fois qu'une exception est levée dans le code, assurez-vous non seulement de consigner le message de l'exception, mais également la trace de la pile.
Les exceptions ne doivent essentiellement jamais être avalées silencieusement sans être enregistrées. Ils peuvent parfois être le moyen le plus simple de vérifier les entrées de l'utilisateur ou les paramètres de configuration. Dans ces situations, la journalisation peut être vraiment votre ami.
De même, rendez votre code résistant aux mauvaises entrées. Plus tôt une mauvaise entrée est détectée, plus il est facile de trouver le problème. Il peut être difficile de retrouver l'origine d'un problème si vous n'obtenez une attente qu'après qu'une valeur a été traitée par plusieurs méthodes. Les contrats peuvent être utiles pour définir les contraintes ici, sinon, vous devez être vigilant et ajouter des validations si vous suspectez un problème à l'avenir.
En savoir plus sur votre débogueur
Tout comme un Jedi ne peut pas être génial sans son sabre laser, vous ne pouvez pas être un grand développeur sans connaître les capacités de votre débogueur. Les débogueurs modernes ont de nombreuses fonctionnalités qui sont pour la plupart sous-utilisées car les développeurs ne les connaissent pas. Par exemple, des points d'arrêt conditionnels ou une représentation définie par l'utilisateur des structures de données peuvent faire la différence entre une session de débogage qui dure toute une journée ou celle qui ne dure que 10 minutes.
Vous n'avez pas besoin de tout savoir par cœur, mais une bonne idée de ce dont votre débogueur est capable et une bonne connaissance des touches de raccourci impliquées pour les fonctionnalités de base telles que pas à pas, pas à pas, définir un point d'arrêt et reprendre l'exécution sont importants. .
Impliquer les gens
Le débogage est difficile car il peut devenir démoralisant, et travailler avec un labyrinthe de code mal documenté peut rapidement conduire à un épuisement physique. Considérez ceci : si vous êtes coincé, faites une pause, allez vous promener, mangez un café, une barre de chocolat - tout ce qui vous aide.
Ne soyez pas gêné si vous devez inclure quelqu'un d'autre - si le comportement du code semble invraisemblable, ou si vous ne savez tout simplement pas où chercher, demandez. Gardez un œil sur ce que fait l'autre personne, à la fois pour apprendre d'elle et pour l'avertir si elle semble se diriger vers une impasse que vous avez déjà observée. Faites-leur savoir ce que vous avez observé et ce que vous pensez, une discussion pourrait apporter un indice.
Testez jusqu'au bout
Lorsque vous pensez avoir résolu le problème, faites tout votre possible pour le tester (dans des limites raisonnables). De toute évidence, les tests unitaires devraient être votre premier port d'escale - les tests unitaires que vous avez introduits pour isoler le problème devraient maintenant réussir, mais tous les autres tests devraient également l'être.
Un problème de haut niveau est souvent causé par de nombreux problèmes de bas niveau - il est facile de découvrir le premier problème de bas niveau, de le corriger, puis de supposer que le problème de haut niveau disparaîtra. Parfois, l'inverse se produit : le comportement de haut niveau se détériore à la suite d'un problème de bas niveau plus important. Dans ce cas, vous devrez continuer à réparer puis à tester jusqu'à ce que vous voyiez que tout fonctionne correctement.
Audit des erreurs potentielles
Les problèmes surviennent fréquemment en groupe. Par exemple, si vous découvrez que quelqu'un a oublié de faire suffisamment d'échappement/encodage sur l'entrée de l'utilisateur dans une instance, le même problème peut survenir dans une autre. Il est beaucoup moins coûteux d'effectuer un audit rapide des problèmes possibles en une seule fois que de laisser chaque problème soulevé comme un problème distinct, impliquant peut-être d'autres ingénieurs menant les mêmes enquêtes que vous venez de terminer.
Considérez les conséquences de votre patch dans la même veine. Cela causera-t-il un problème ailleurs qui ne pourra peut-être pas être résolu à court terme ? Cela aura-t-il un impact sur les correctifs ou les mises à niveau ? S'agit-il d'une réparation importante à ce stade du cycle de vie de votre produit ? Cela vaut généralement toujours la peine de comprendre ce qui ne va pas, mais il est parfois plus sûr de laisser le code cassé - potentiellement avec une réparation "pansement" qui s'attaque aux symptômes mais pas à la cause - et de laisser le remède complet pour la prochaine version. Cela ne signifie pas que vous devez laisser le rapport de bogue tel quel.
Si vous avez une suggestion de réparation, essayez de créer un fichier de correctif et de l'ajouter au rapport de bogue (en indiquant clairement quelles versions de quels fichiers nécessitent un correctif, bien sûr). Au minimum, fournissez une explication détaillée de votre recherche dans le rapport de bogue pour éviter de perdre du temps plus tard. Un statut de bogue de "Résoudre la prochaine version" (ou quel que soit votre équivalent) devrait indiquer simplement cela, et non "Il est peu probable que nous résolvions vraiment cela, mais nous le retarderons d'une version à la fois".
Conclusion
Ces recommandations ne peuvent pas faire de vous un débogueur professionnel en un jour ou deux, mais elles vous aideront sûrement à démarrer dans la bonne direction si elles sont suivies avec patience et bonnes pratiques. Un code de haute qualité ne se produit pas par accident - il faut de la patience et de la précision.
C'était tout pour cet article. Faites-moi savoir ce que vous pensez des conseils de débogage ci-dessus et n'hésitez pas à ajouter votre approche, vos conseils et astuces pour devenir un débogueur professionnel dans les commentaires ci-dessous.
Continue de lire!