Suite de ma petite série d'articles sur la qualité. Aujourd'hui, nous allons voir comment nous préparer à déboguer.
Cet article fait partie d'une série d'articles visant à énumérer les différents éléments de qualité à mettre en place au démarrage d'un projet.
Le debugging est l'une des tâches les plus importantes et les plus courantes pour tout développeur, qui consiste à trouver et de corriger les erreurs dans votre code. Le processus peut s'avérer difficile et fastidieux, car les erreurs peuvent être difficiles à identifier et à reproduire.
Ainsi, il est important de maîtriser les techniques qui permettent de simplifier ce processus
Les derniers articles ont été très centrés sur Python, je vais essayer d'être un peu plus ouvert sur d'autres langages dans cet article. En effet, les techniques peuvent être assez différentes d'un langage à l'autre.
L'objectif de cet article est donc d'explorer les principales techniques de debugging utilisées lors de l'écriture et du test du code.
Lorsqu'on écrit du code, il est courant de faire quelques erreurs. C'est normal et ça fait partie du processus de création.
Le debugging est l'activité qui consiste à identifier et corriger ces erreurs. Il s'agit d'une étape essentielle du développement, les erreurs pouvant causer des dysfonctionnements important une fois en production.
Quels que soient les outils utilisés, la technique globale reste à peu près la même :
Voyons quels sont les outils qui nous aident à réaliser tout ça.
Le debugging par le print est probablement la technique de debugging la plus courante et la plus facile à mettre en place. Elle consiste à ajouter des instructions "print()" dans votre code pour afficher des valeurs à des points clés de votre programme, afin de voir ce qui se passe. Vous pouvez utiliser cette technique pour afficher des valeurs de variables, des messages d'erreur ou pour déboguer des boucles et des fonctions. Par exemple :
x = 5
y = 10
print("La valeur de x est :", x)
print("La valeur de y est :", y)
Dans un langage comme PHP, qui vient sans debugger natif, c'est une technique de debugging très populaire. On utilise alors souvent la fonction var_dump()
, qui permet d'afficher les informations détaillées sur une variable ou une expression, y compris son type, sa valeur et sa longueur.
$fruit = array('pomme', 'banane', 'orange');
var_dump($fruit);
Ce code affiche le contenu de la variable $fruit
ainsi que son type et sa longueur :
array(3) {
[0]=>
string(5) "pomme"
[1]=>
string(6) "banane"
[2]=>
string(6) "orange"
}
D'autres fonctions utiles pour le debugging en PHP incluent print_r()
, qui affiche les informations structurées sur une variable ou une expression, et debug_backtrace()
, qui affiche la trace de la pile d'appels.
En javascript, on utilisera console.log()
pour utiliser cette technique.
C'est assez pratique pour comprendre ce qui se passe dans le code, et ça a le gros avantage d'être très rapide, mais cela implique plusieurs inconvénients :
print
et de var_dump
, ce qui peut être fastidieux.Le debug à coup de print est donc conseillé pour résoudre de tout petits problèmes, simples à identifier. Pour des problèmes plus complexes, il est recommandé d'utiliser des outils de debugging plus avancés tels que ceux que nous allons voir ensuite.
Les points d'arrêt sont des marqueurs qui permettent de stopper l'exécution d'un programme à un endroit précis pour inspecter son état.
En python, vous pouvez utiliser cette technique à l'aide de la commande pdb
dans la ligne de commande. Par exemple :
def divide(x, y):
import pdb; pdb.set_trace() # point d'arrêt
result = x / y
return result
print(divide(10, 2))
L'exécution de ce code entraînera l'arrêt du programme au niveau du point d'arrêt et ouvrira une console interactive où vous pourrez inspecter l'état du programme. Vous pouvez alors vérifier le contenu d'une variable en tapant directement son nom, ou tester du code.
Vous pouvez aussi suivre le déroulement de votre programme. Voici les principales commandes de pdb
:
step
ou s
: exécute la ligne courante et arrête à la ligne suivante, même si elle est dans une autre fonctionnext
ou n
: exécute la ligne courante et arrête à la ligne suivante dans la même fonctioncontinue
ou c
: continue l'exécution du code jusqu'à atteindre un point d'arrêt ou la fin du programmereturn
ou r
: exécute le code jusqu'à ce qu'au retour de la fonction courantelist
ou l
: affiche le code autour de la ligne couranteprint
ou p
: affiche la valeur d'une variablehelp
ou h
: affiche l'aidequit
ou q
: quitte pdb et interrompt l'exécution du codeEnfin, je vous conseille de préférer ipdb
à pdb
. Il s'agit d'une implémentation qui n'est pas dans la librairie standard, mais qui offre l'avantage d'ouvrir une console interactive basée sur l'excellent ipython. Vous bénéficierez alors d'une interface en ligne de commande améliorée avec des options d'auto-complétion complète. Comme je le dis souvent : "tab tab tab"
Pour utiliser ipdb
, il vous faudra l'installer :
pip install ipdb
D'autres langages offrent la même mécanique de point d'arrêt. On peut citer pry dans le monde ruby par exemple.
require 'pry'
def greet(name)
puts "Hello, #{name}!"
end
binding.pry # point d'arrêt
greet("John")
Des solutions existent également pour PHP, bien que moins pratiques (voir phpdbg par exemple).
En Javascript, il existe le mot clé debugger
. Le point d'arrêt est alors en place lorsqu'on ouvre la console de débogage du navigateur.
Les environnements de développement intégrés modernes (IDE) offrent une manière plus graphique de déboguer votre code. En effet, vous pouvez placer des points d'arrêt directement dans l'éditeur de code en cliquant sur la marge à gauche de la ligne de code où vous souhaitez les placer. Une fois que le programme atteint un point d'arrêt, vous pouvez utiliser les fonctionnalités intégrées de l'IDE pour inspecter l'état du programme et suivre son exécution.
Visual Studio Code (VSCode), par exemple, offre une vue de débogage qui permet de visualiser les variables, d'exécuter du code pas à pas et de contrôler l'exécution du programme. Vous pouvez facilement naviguer dans votre code et ajouter des points d'arrêt à la volée, sans avoir à modifier votre code source.
VSCode propose également des configurations prêtes à l'emploi pour la plupart des frameworks du marché, vous permettant de déboguer votre application en toute simplicité. Vous pouvez, par exemple, déboguer une application Django ou une application Flask en utilisant les configurations prédéfinies de VSCode.
Même si j'ai un faible pour ipdb, l'utilisation de points d'arrêt dans un IDE est un moyen efficace de déboguer votre code, car elle permet une inspection de l'état du programme de manière plus ergonomique. Il suffit souvent de passer sa souris au-dessus d'une variable pour voir sa valeur par exemple. De plus, vous pouvez voir en même temps votre console de débogage et votre code source, ce qui est souvent pratique.
Parlons un peu de PHP. Comme je l'ai dit plus haut, le langage n'offre pas de débogueur dans sa librairie standard. Pour bénéficier de cela, il vous faudra installer Xdebug. C'est assez étonnant, mais, hey, c'est historique.
Je termine par une technique assez spécifique, parce que Python le permet vraiment facilement. Dans les faits, ça pourrait être vrai avec d'autres langages (irb
pour Ruby ou même php -a
), mais c'est vraiment moins pratique.
ipython est une interface interactive avancée pour Python, dont j'ai parlé un peu plus tôt. Il permet de tester son code pas à pas et d'explorer les variables. Vous pouvez importer votre code dans ipython et l'exécuter pas à pas pour voir comment il se comporte. Voici un exemple :
from my_maths import divide
divide(10, 2) # OK
divide(10, 0) # Erreur
J'ai une approche du code qui est résolument orienté vers l'expérimentation. J'utilise donc très souvent ipython pour tester le comportement des différentes fonctions que j'utilise, pour tester des algorithmes, etc.
Un cas d'utilisation très courant pour moi, c'est la manipulation des modèles Django. Je vais pouvoir tester très rapidement mes filtres pour vérifier qu'ils me renvoient ce que j'attends. Je vais aussi bénéficier de l'auto-complétion pour vérifier rapidement les attributs et les valeurs des modèles lorsque je prépare mes templates.
Certains préfèrent utiliser JupyterLab, un notebook qui a l'avantage de conserver vos commandes. C'est très équivalent, c'est juste présenté différemment.
Certains outils, comme Django ou Symfony, proposent une debug toolbar, comme par exemple la Django Debug Toolbar. Elles offrent de nombreuses informations pour comprendre comment une page web a été générée.
Elles permettent d'inspecter le contexte, les réglages, et détaillent les requêtes qui ont été passées à la base de données, entre autre.
Vous vous ferez gagner beaucoup de temps à les utiliser.
Plus on debug, plus on devient efficace pour débugger.
Voici mes conseils pour trouver les problèmes au pus vite :
Et voilà, comme dirait Forest Gump :
C'est tout ce que j'avais à dire sur le debogage.
La prochaine fois, on parlera de logging et de monitoring.
2022 - tominardi.fr