Déboguez des rapports de bugs que vous n'avez pas écrits avec un workflow pratique pour reproduire, isoler UI/API/BD et demander un correctif minimal et testable.

Déboguer un rapport de bug que vous n'avez pas écrit est plus compliqué parce que la carte mentale du créateur vous manque. Vous ne savez pas ce qui est fragile, ce qui est « normal » ou quelles concessions ont été prises. Un petit symptôme (un bouton, une faute de frappe, un écran lent) peut venir d'un problème plus profond dans l'API, la base de données ou un job en arrière‑plan.
Un rapport de bug utile vous donne quatre choses :
La plupart des rapports ne donnent que le dernier : « Sauvegarde qui ne marche pas », « c'est cassé », « erreur aléatoire ». Ce qui manque, c'est le contexte qui le rend répétable : rôle utilisateur, enregistrement précis, environnement (prod vs staging), et si cela a commencé après un changement.
L'objectif est de transformer un symptôme vague en une reproduction fiable. Une fois que vous pouvez le produire à la demande, ce n'est plus mystérieux. C'est une série de vérifications.
Ce que vous pouvez contrôler tout de suite :
« Fini » n'est pas « je pense que j'ai réparé ». Fini, c'est : vos étapes de reproduction passent après un petit changement, et vous avez rapidement retesté le comportement adjacent que vous auriez pu affecter.
Le moyen le plus rapide de perdre du temps est de changer plusieurs choses en même temps. Geler votre point de départ fait que chaque résultat de test a du sens.
Choisissez un environnement et tenez‑vous‑y jusqu'à pouvoir reproduire le problème. Si le rapport vient de la production, confirmez d'abord là‑bas. Si c'est risqué, utilisez le staging. Le local convient si vous pouvez reproduire fidèlement les données et les paramètres.
Ensuite, identifiez précisément quel code tourne : version, date de build et tous les feature flags ou configs qui influencent le flux. De petites différences (intégrations désactivées, URL d'API différente, jobs en arrière‑plan manquants) peuvent transformer un vrai bug en fantôme.
Créez un setup de test propre et répétable. Utilisez un compte frais et des données connues. Si possible, réinitialisez l'état avant chaque tentative (déconnexion, vider le cache, partir du même enregistrement).
Notez vos hypothèses au fur et à mesure. Ce n'est pas du remplissage ; ça vous évitera de vous contredire plus tard.
Un modèle de note baseline :
Si la reproduction échoue, ces notes vous indiquent quelle variable changer ensuite, un bouton à la fois.
Le gain le plus rapide est de transformer une plainte vague en quelque chose qu'on peut exécuter comme un script.
Commencez par réécrire le rapport en une courte histoire utilisateur : qui fait quoi, où, et ce qu'il attendait. Ajoutez ensuite le résultat observé.
Exemple de réécriture :
"En tant qu'admin facturation, quand je change le statut d'une facture en Paid et que je clique sur Enregistrer sur la page facture, le statut devrait persister. Au lieu de ça, la page reste identique et le statut ne change pas après actualisation."
Puis, capturez les conditions qui rendent le rapport vrai. Les bugs reposent souvent sur un détail manquant : rôle, état de l'enregistrement, locale ou environnement.
Entrées clés à noter avant de cliquer :
Collectez des preuves tant que le comportement original est encore présent. Des captures d'écran aident, mais un court enregistrement vidéo est mieux car il capture le timing et les clics exacts. Notez toujours un horodatage (avec timezone) pour pouvoir retrouver les logs plus tard.
Trois questions clarifiantes qui enlèvent le plus d'incertitude :
Ne commencez pas par deviner la cause. Faites en sorte que le problème se produise volontairement, de la même manière, plus d'une fois.
D'abord, exécutez les étapes du rapporteur exactement comme elles sont écrites. Ne les « améliorez » pas. Notez le premier endroit où votre expérience diverge, même si ça semble mineur (libellé de bouton différent, champ manquant, texte d'erreur légèrement différent). Cette première différence est souvent l'indice.
Un workflow simple qui marche dans la plupart des applis :
Une fois répétable, variez une chose à la fois. Tests à variable unique qui paient souvent :
Terminez avec un court script de repro que quelqu'un d'autre peut exécuter en 2 minutes : état de départ, étapes, entrées et la première observation échouée.
Avant de lire tout le code, décidez quelle couche échoue.
Demandez‑vous : le symptôme est‑il uniquement dans l'UI, ou bien les données et réponses API sont‑elles aussi affectées ?
Exemple : "Mon nom de profil ne s'est pas mis à jour." Si l'API renvoie le nouveau nom mais que l'UI affiche toujours l'ancien, suspectez l'état UI/caching. Si l'API n'a jamais sauvegardé, il s'agit probablement de l'API ou de la BD.
Questions rapides de tri que vous pouvez répondre en quelques minutes :
Les vérifications UI portent sur la visibilité : erreurs console, onglet Réseau, état obsolète (UI qui ne refait pas de fetch après sauvegarde, ou qui lit d'un cache ancien).
Les vérifications API portent sur le contrat : payload (champs, types, IDs), code de statut et corps d'erreur. Un 200 avec un corps surprenant peut être aussi important qu'un 400.
Les vérifications BD portent sur la réalité : lignes manquantes, écritures partielles, violations de contrainte, mises à jour qui touchent zéro ligne parce que le WHERE ne correspondait pas.
Pour rester orienté, esquissez une petite carte : quelle action UI déclenche quel endpoint, et quelles tables il lit ou écrit.
La clarté vient souvent de suivre une requête réelle du clic jusqu'à la base et retour.
Capturez trois points d'ancrage depuis le rapport ou votre repro :
Si vous n'avez pas de correlation ID, ajoutez‑en un dans votre gateway/backend et incluez‑le dans les en‑têtes de réponse et les logs.
Pour ne pas être noyé par le bruit, capturez uniquement ce qui est nécessaire pour répondre à « Où ça a échoué et pourquoi ? » :
Signaux à surveiller :
Si « ça marchait hier » et pas aujourd'hui, soupçonnez une dérive d'environnement : flags changés, secrets tournés, migrations manquantes ou jobs arrêtés.
Le bug le plus facile à fixer est une petite expérience répétable.
Réduisez tout : moins de clics, moins de champs, l'ensemble de données le plus petit qui échoue encore. Si ça n'arrive qu'avec « clients avec beaucoup d'enregistrements », essayez de créer un cas minimal qui déclenche encore le bug. Si vous ne pouvez pas, c'est un indice que le bug est lié au volume de données.
Séparez « état mauvais » de « code mauvais » en réinitialisant volontairement l'état : compte propre, tenant ou dataset frais, build connu.
Une façon pratique de garder le repro clair est un tableau d'entrée compact :
| Donné (setup) | Quand (action) | Attendu | Obtenu |
|---|---|---|---|
| Rôle utilisateur : Éditeur ; un enregistrement avec Statut=Draft | Cliquer sur Enregistrer | Toast « Saved » + timestamp mis à jour | Le bouton affiche un spinner puis s'arrête ; pas de changement |
Rendez le repro portable pour que quelqu'un d'autre puisse le lancer rapidement :
Le chemin le plus rapide est souvent ennuyeux : changez une chose, observez, gardez des notes.
Erreurs fréquentes :
Un exemple réaliste : un ticket dit « Export CSV est vide. » Vous testez en admin et voyez des données. L'utilisateur a un rôle restreint et l'API renvoie une liste vide à cause d'un filtre de permission. Si vous ne corrigez que l'UI pour afficher « Pas de lignes », vous manquez la vraie question : ce rôle doit‑il pouvoir exporter, ou le produit doit‑il expliquer pourquoi c'est filtré ?
Après tout correctif, rejouez les mêmes étapes exactes, puis testez un scénario adjacent qui devrait toujours marcher.
Vous obtiendrez de meilleures réponses d'un collègue (ou d'un outil) si vous apportez un paquet serré : étapes répétables, une couche probablement en échec et des preuves.
Avant que quiconque change du code, confirmez :
Faites ensuite une courte passe de régression : essayez un rôle différent, une seconde fenêtre privée, une fonctionnalité voisine utilisant le même endpoint/table, et une saisie edge case (vide, texte long, caractères spéciaux).
Un message support dit : « Le bouton Enregistrer ne fait rien sur le formulaire Modifier Client. » Un suivi révèle que ça n'arrive que pour les clients créés avant le mois dernier, et uniquement quand on change l'email de facturation.
Commencez par l'UI et supposez d'abord l'échec le plus simple. Ouvrez l'enregistrement, faites la modification et cherchez des signes que « rien » est en fait quelque chose : bouton désactivé, toast caché, message de validation qui ne se render pas. Ouvrez ensuite la console du navigateur et l'onglet Réseau.
Ici, cliquer sur Enregistrer déclenche une requête, mais l'UI n'affiche jamais le résultat parce que le frontend ne considère que 200 comme succès et ignore les erreurs 400. L'onglet Réseau montre une réponse 400 avec un corps JSON comme : {"error":"billingEmail must be unique"}.
Vérifiez ensuite que l'API échoue vraiment : reprenez le payload exact de la requête et rejouez‑le. S'il échoue hors de l'UI aussi, arrêtez de traquer des bugs d'état frontend.
Puis regardez la base : pourquoi l'unicité échoue‑t‑elle seulement pour les anciens enregistrements ? Vous découvrez que des clients legacy partagent un billing_email placeholder depuis des années. Un nouveau contrôle d'unicité bloque maintenant la sauvegarde de tout client qui conserve ce placeholder.
Repro minimal à transmettre :
billing_email = [email protected].billingEmail must be unique.Critère d'acceptation : quand l'API renvoie une erreur de validation, l'UI affiche le message, conserve les modifications de l'utilisateur et indique précisément le champ en échec.
Une fois le bug reproductible et la couche probable identifiée, demandez de l'aide de façon à obtenir un petit patch sûr.
Préparez un simple « dossier » : étapes de repro minimales (avec entrées, environnement, rôle), attendu vs réel, pourquoi vous pensez que c'est UI/API/BD, et le plus petit extrait de log montrant l'échec.
Ensuite, formulez la demande de façon ciblée :
Si vous utilisez une plateforme vibe‑coding comme Koder.ai (koder.ai), cette approche en dossier maintient la suggestion focalisée. Ses snapshots et rollback aident aussi à tester de petits changements en sécurité et à revenir à une baseline connue.
Confiez à un développeur expérimenté les changements touchant à la sécurité, aux paiements, aux migrations de données ou à tout ce qui pourrait corrompre la production. Confiez aussi si la modification devient plus grosse qu'un petit patch ou si vous ne pouvez pas expliquer le risque en termes simples.
Commencez par réécrire le rapport en un script reproductible : qui (rôle), où (page/flux), quelles entrées exactes (IDs, filtres, payload), ce que vous attendiez et ce que vous avez vu. S'il manque un de ces éléments, demandez un compte exemple et un ID d'enregistrement exemple pour pouvoir exécuter le même scénario de bout en bout.
Choisissez un seul environnement et restez-y jusqu'à ce que vous puissiez reproduire le bug. Puis notez la build/version, les feature flags, la config, le compte/role de test et les données exactes utilisées. Cela évite de « corriger » un bug qui n'existe que parce que votre configuration diffère de celle du rapporteur.
Faites-le se produire deux fois avec les mêmes étapes et entrées, puis retirez tout ce qui n'est pas nécessaire. Visez 3–6 étapes depuis un état propre avec un enregistrement réutilisable ou un corps de requête. Si vous ne pouvez pas réduire davantage, cela peut indiquer un problème lié au volume de données, au timing ou à un job en arrière-plan.
Ne changez rien tout de suite. Exécutez d'abord les étapes du rapporteur à la lettre et notez le premier endroit où votre expérience diverge (libellé de bouton différent, champ manquant, texte d'erreur différent). Cette première divergence est souvent l'indice de la condition réelle qui déclenche le bug.
Vérifiez si les données ont vraiment changé. Si l'API renvoie la nouvelle valeur mais que l'UI affiche l'ancienne, il s'agit probablement d'un problème d'état UI, de cache ou de re-fetch. Si la réponse de l'API est incorrecte ou si la sauvegarde n'a jamais lieu, concentrez-vous sur l'API ou la BD. Si la ligne en BD ne s'actualise pas (ou affecte zéro ligne), le problème est au niveau de la persistance ou des conditions de requête.
Vérifiez qu'une requête réseau est déclenchée lors du clic, inspectez le payload de la requête et le corps de la réponse, pas seulement le code d'état. Capturez un timestamp (avec fuseau) et un identifiant utilisateur pour retrouver les logs backend. Un 200 « réussi » avec un corps inattendu peut être aussi important qu'un 400/500.
Faites varier une seule chose à la fois : rôle, enregistrement (nouveau vs ancien), navigateur/appareil, session propre (navigation privée/cache vidé) et réseau. Les tests à variable unique montrent quelle condition compte et évitent de courir après des coïncidences causées par plusieurs changements simultanés.
Changer plusieurs variables à la fois, tester sur un environnement différent de celui du rapporteur et ignorer rôles/permissions sont les plus grands pertes de temps. Autre erreur fréquente : corriger le symptôme dans l'UI alors qu'une erreur de validation API/BD subsiste. Rejouez toujours le repro exact après votre changement puis testez un scénario voisin.
« Fini » signifie : le repro minimal original passe maintenant, et vous avez retesté un flux voisin susceptible d'être impacté. Gardez la vérification concrète : signal visible de succès, réponse HTTP correcte ou changement attendu en BD. Évitez « je pense que c'est réparé » sans rejouer les mêmes entrées sur la même baseline.
Fournissez un dossier serré : étapes minimales avec entrées exactes, environnement/build/flags, compte et rôle de test, attendu vs réel, et une preuve (requête/réponse, texte d'erreur ou extrait de log avec timestamp). Puis demandez le plus petit patch possible et incluez un mini plan de test. Si vous utilisez Koder.ai, associer ce dossier à des snapshots/rollback facilite les tests sûrs et la restauration si besoin.