Une méthode systématique
Reproduire, isoler, tester une hypothèse à la fois.
Objectifs
À la fin de cette leçon, vous saurez :
- appliquer une démarche en six étapes pour tout bug ;
- éviter le piège du « changement au hasard » ;
- isoler un problème par bissection ;
- documenter ce que vous avez appris de chaque bug.
🔗 Pour vous rafraîchir la mémoire : lire une stack trace · déboguer pas à pas
Le piège : modifier au hasard
Face à un bug, l'instinct débutant est de changer quelque chose, relancer, changer autre chose… Vingt minutes plus tard : trois « corrections » ajoutées, bug toujours là, code devenu incompréhensible. Ce mode opératoire échoue car il ne produit aucune information sur la cause.
La méthode ci-dessous transforme chaque étape en information.
Les six étapes
1. REPRODUIRE : trouver les gestes exacts qui déclenchent le bug
2. LIRE : message d'erreur complet, jusqu'au bout
3. LOCALISER : stack trace, console.log, réduire la zone suspecte
4. HYPOTHÉSER : formuler UNE cause précise (« i commence à 0 au lieu de 1 »)
5. TESTER : corriger UNIQUEMENT cette hypothèse, relancer
6. VÉRIFIER : cas normal + cas limites + rien d'autre n'a cassé
Étape 1 — Reproduire
Un bug qu'on ne sait pas provoquer ne peut pas être corrigé. Notez la séquence exacte : données d'entrée, commandes, contexte. Si le bug n'apparaît qu'une fois sur dix, c'est déjà une information (probable lien avec un état ou un timing).
Étapes 2 et 3 — Lire puis localiser
Le message d'erreur a été écrit pour vous. Type + message + stack trace orientent vers la zone ; console.log des valeurs intermédiaires réduit encore le cercle.
Étape 4 — Une hypothèse à la fois
Formulez-la en phrase testable : « si je change X en Y, alors Z devrait afficher W ». Deux hypothèses testées simultanément produisent des résultats ininterprétables.
Étape 5 — Un seul changement
Modifiez exactement ce que prévoit l'hypothèse. Si ça marche : cause confirmée. Sinon : annulez le changement avant d'en tester un autre — sinon vous accumulez les modifications aveugles.
Étape 6 — Vérifier large
Le bug corrigé, rejouez : le cas nominal, les cas limites (vide, zéro, négatif), et les exercices précédents qui utilisaient la fonction réparée.
Isoler par bissection
Quand la zone suspecte reste trop grande : coupez-la en deux.
100 lignes suspectes ?
→ commenter la moitié (ou court-circuiter avec des valeurs factices)
bug toujours là ? → il vit dans l'autre moitié
bug disparu ? → il vit dans cette moitié
→ recommencer sur la moitié restante
7 essais suffisent pour passer de 100 lignes à 1
En pratique : remplacer une entrée douteuse par une valeur connue bonne (const entree = [1, 2, 3]; // TEMP) sépare immédiatement les problèmes « données » des problèmes « traitement ».
S'appuyer sur Git
Vous versionnerez bientôt tout votre travail (chapitre suivant). Deux usages immédiats :
git diffmontre exactement ce qui a changé depuis le dernier état fonctionnel : souvent, le bug est dans ces lignes ;- revenir en arrière (
git checkout -- fichier) annule proprement une piste abandonnée, sans traces.
Documenter le bug résolu
Trois lignes dans vos notes de cours :
Symptôme : moyenne([12,14,16]) → 21
Cause : division par length - 1 au lieu de length
Leçon : vérifier les résultats attendus AVANT de croire un code qui tourne
Chaque bug ainsi noté devient un réflexe permanent. C'est ainsi qu'on devient « celui qui trouve vite » : non par don, mais par bibliothèque personnelle de causes déjà rencontrées.
Exercice
Appliquez la méthode à ce programme, sans l'exécuter d'abord :
function filtrerMajeurs(personnes) {
const resultat = [];
for (const personne of personnes) {
if (personne.age > 18) {
resultat.push(personne.nom);
}
}
return resultat;
}
const groupe = [
{ nom: "Ana", age: 19 },
{ nom: "Bob", age: 18 },
{ nom: "Cléo", age: 21 },
];
console.log(filtrerMajeurs(groupe));
// attendu : ["Ana", "Cléo"] ← Bob, 18 ans exactement, doit-il figurer ?
- Quelle est l'étape 0 de la méthode ici (avant même reproduire) ?
- Le programme plante-t-il ? Quelle famille de problème ?
- Formulez l'hypothèse sous forme de phrase testable.
- Quelle correction unique proposez-vous ?
Résumé
- Reproduire → lire → localiser → hypothèse unique → un seul changement → vérifier large.
- La bissection divise la zone suspecte par deux à chaque essai.
- Git diff localise les changements récents ; git checkout les annule.
- Chaque bug résolu et noté enrichit votre méthode permanente.
Correction disponibleCherchez d’abord par vous-même.Voir la correction
Correction
Réponses détaillées
1. Définir le contrat ! « Majeur » veut dire 18 ans inclus ou exclu ? Sans réponse écrite, aucune correction n'est possible. C'est l'étape invisible mais décisive : beaucoup de « bugs » sont en réalité des spécifications floues.
2. Non, aucun crash : erreur logique, la plus silencieuse. Aucun outil automatique ne la signalera.
3. Phrase testable : « si je remplace > par >=, alors filtrerMajeurs(groupe) renverra ["Ana", "Bob", "Cléo"] ». On connaît à l'avance le résultat attendu de la modification — c'est ce qui rend le test informatif.
4. Selon le contrat choisi :
- majorité = 18 inclus :
if (personne.age >= 18); - majorité = strictement plus de 18 : le code était correct, et le « bug » était dans l'attendu.
Dans les deux cas, notez la discipline : une seule modification, résultat prédit avant exécution, puis vérification sur d'autres jeux de données (liste vide, âge négatif, doublons).