Ouvrez la page de statistiques de presque n'importe quel bug tracker, et vous trouverez beaucoup de chiffres. Le total des tickets créés. Un camembert des sévérités. Un temps moyen de résolution. Une barre par assigné.
Presque aucun ne répond à la question qu'une équipe se pose vraiment le lundi matin : est-ce qu'on suit le rythme, ou est-ce qu'on prend du retard ?
Cette question a une réponse courte, et il faut quatre chiffres pour la donner. Cet article passe en revue ces quatre chiffres, les métriques populaires qui induisent en erreur sans qu'on s'en aperçoive, et une revue hebdomadaire de cinq minutes à mener à partir d'eux. C'est aussi le raisonnement derrière le bandeau de synthèse que je viens d'ajouter en haut du tableau BugDump.
Les métriques qui ont l'air utiles et ne le sont pas
Le total des bugs créés depuis le début. Il ne fait que monter. Un chiffre qui ne peut que monter vous dit l'âge du projet, pas sa santé.
Le nombre de rapports de bug. Les rapports mesurent le trafic autant que la qualité. Un seul bouton de paiement cassé peut produire quarante rapports en un après-midi, et c'est un bug, pas quarante. Comptez les rapports, et une version populaire ressemble à une catastrophe ; comptez les bugs, et elle ressemble à un mardi comme les autres.
Les bugs par sévérité, en camembert. Ce graphique décrit le backlog sans dire quoi en faire. Personne n'a jamais regardé un camembert puis fermé un ticket.
Le temps moyen de correction. Celui-ci fait de vrais dégâts, parce qu'il a l'air rigoureux. J'y reviendrai.
Ces métriques ont un point commun : ce sont des stocks, pas des flux. Elles décrivent une pile. Les questions utiles portent sur le sens dans lequel la pile évolue et sur ce qui reste coincé tout en bas.
1. Le backlog ouvert, et dans quel sens il évolue
Commencez par le chiffre le plus simple qui soit : combien de bugs sont ouverts en ce moment. Dans BugDump, ce sont toutes les tâches qui n'ont pas atterri dans une colonne fermée.
Seul, ce nombre veut dire peu de chose. Vingt-neuf bugs ouverts, c'est normal pour une équipe et alarmant pour une autre. Ce qui compte, c'est le sens, et le sens n'est qu'une soustraction sur une période :
variation nette = bugs ouverts − bugs résolus, sur la même période
Négative, le backlog diminue. Positive, il grossit. Zéro avec de l'activité, vous suivez exactement le rythme ; zéro sans activité, personne n'a touché à rien, ce qui est une autre situation et mérite un autre libellé.
C'est pour ça que le bandeau de synthèse n'affiche pas seulement « 29 à traiter ». Il dit en attente en baisse de 4 sur la période, en attente en hausse de 6 sur la période, en attente stable ou période calme, rien n'a bougé. Le chiffre donne l'échelle ; la phrase donne le sens.
Un backlog qui grossit plusieurs périodes de suite est rarement un problème de productivité des développeurs. C'est presque toujours un problème de tri : les doublons ne sont pas fusionnés, les décisions de ne pas corriger ne sont pas prises, et chaque rapport s'installe pour de bon.
2. Corrigés contre ouverts, comparés à la période précédente
Le deuxième chiffre est le nombre de bugs résolus sur la période, affiché face à la période précédente de même durée.
Comparer avec la période juste avant, plutôt qu'avec une moyenne historique, compte pour deux raisons. Cela neutralise la saisonnalité : une quinzaine calme pendant les vacances est comparée à la quinzaine chargée qui la précède, pas à votre meilleur mois. Et cela rend les semaines de release lisibles : une release qui corrige tout un groupe de bugs apparaît comme un saut, pas comme du bruit.
Mieux encore, regardez les ouverts et les résolus sur le même graphique. J'affiche les bugs ouverts au-dessus de l'axe, les bugs résolus en dessous, et le backlog comme une ligne qui traverse les deux. Quand les deux zones se répondent en miroir, vous suivez le rythme. Quand celle du haut l'emporte à chaque fois, la ligne monte, et vous voyez exactement quels jours ça a commencé.
3. Le temps de correction médian, pas la moyenne
Le temps de correction est la métrique que la plupart des équipes veulent et que la plupart des outils calculent mal.
La définition est simple : pour chaque bug résolu sur la période, mesurez le temps entre son ouverture et sa résolution. Reste à savoir comment résumer ces durées, et la réponse ne devrait presque jamais être la moyenne.
Prenons un exemple. Votre équipe corrige dix bugs cette quinzaine. Neuf sont corrigés en moins d'une journée. Le dixième est un bug d'il y a quatre mois que quelqu'un a enfin fermé pendant une séance de nettoyage, 120 jours après sa création.
Moyenne : (9 × 1 + 120) ÷ 10 = 12,9 jours
Médiane : 1 jour
La moyenne dit que votre équipe met deux semaines à corriger un bug. La médiane dit que votre équipe corrige les bugs le lendemain, et c'est elle qui a raison. Pire, la moyenne punit le nettoyage : la semaine où vous fermez enfin les vieux tickets est celle où votre moyenne paraît catastrophique, ce qui apprend à tout le monde à laisser les vieux tickets tranquilles.
La médiane résiste à cette valeur aberrante, elle suit donc ce que vit un bug typique. C'est ce que le bandeau de synthèse affiche sous Résolution médiane, en minutes, en heures ou en jours selon l'échelle.
Elle a une vraie faiblesse : elle ne compte que les bugs effectivement corrigés. Un bug jamais résolu n'entre jamais dans le calcul, si bien qu'une équipe peut avoir une superbe médiane tout en abandonnant discrètement ses problèmes les plus durs. C'est précisément pour ça qu'il faut le quatrième chiffre.
4. Le plus vieux bug ouvert
La médiane décrit le milieu. Le plus vieux bug ouvert décrit la queue de la distribution, et c'est là que la confiance s'effrite.
Affichez son âge juste à côté de la médiane : 5 mois, avec l'ID et le titre en dessous. Rendez-le cliquable, pour que le consulter tienne en un clic, pas en une recherche.
Un bug ouvert depuis cinq mois n'est presque jamais un bug que personne n'a su corriger. C'est une décision que personne n'a prise. Le regarder impose l'une de trois issues honnêtes :
Le corriger, parce qu'il s'avère petit.
Le planifier, parce qu'il compte et qu'il est resté orphelin.
Le fermer délibérément, comme « ne sera pas corrigé » ou obsolète, et expliquer pourquoi à la personne qui l'a signalé.
N'importe laquelle des trois vaut mieux qu'un quatrième mois de silence. Et une fois le plus vieux bug traité, le suivant prend sa place : le chiffre continue de raccourcir la queue.
Bonus : d'où viennent les rapports
Les quatre chiffres ci-dessus vous disent si vous suivez le rythme. Ils ne vous disent pas pourquoi une semaine s'est mal passée.
Pour ça, ventilez les rapports de la même période par navigateur, système d'exploitation, type d'appareil et page. Une régression se répartit rarement de façon uniforme. Quand un tiers des rapports de la semaine viennent de Safari sur iOS, ou que la page la plus signalée est une étape du paiement livrée jeudi, vous avez trouvé la cause avant d'ouvrir le moindre rapport.
Dans BugDump, déplier le bandeau de synthèse affiche exactement cette ventilation à côté du graphique, avec les pages classées par nombre de rapports. Un clic sur une puce de navigateur, de système ou d'appareil filtre le tableau dessus : on passe de « il y a un souci avec Safari » aux bugs Safari en un clic.
C'est aussi là que compter les rapports plutôt que les bugs est le bon choix. Quarante rapports d'un même bug, ce sont quarante données sur les personnes qui l'ont rencontré.
Choisir la période
La période change ce que les chiffres peuvent vous dire, alors choisissez-la selon la question que vous posez :
7 jours pour les semaines de release, quand vous voulez voir l'effet d'un déploiement.
14 jours comme valeur par défaut raisonnable : assez long pour lisser le bruit quotidien, assez court pour réagir.
30 ou 90 jours pour les questions de tendance et les rétrospectives.
Méfiez-vous des médianes sur de courtes périodes dans les petits projets. La médiane de trois corrections est un fait sur trois bugs, pas sur votre équipe.
Définir « résolu » honnêtement
Chacune de ces métriques dépend de ce qui compte comme résolu, et c'est là que les tableaux de bord mentent le plus souvent.
Si Prêt pour la QA ou Mergé compte comme résolu, votre temps médian de correction mesure la vitesse d'écriture du code, pas le moment où les utilisateurs cessent de tomber sur le bug. Si Ne sera pas corrigé ne compte pas, votre backlog traîne des décisions déjà prises.
Dans BugDump, un bug est résolu quand il entre dans une colonne de type fermé, et le ressortir de cette colonne le rouvre. Quel que soit votre outil, vérifiez que ses états fermés veulent dire ce que vos utilisateurs entendraient par « corrigé ».
La revue hebdomadaire de cinq minutes
Avec ces quatre chiffres sur un seul écran, la revue hebdomadaire des bugs n'est plus une réunion mais une checklist :
Le backlog baisse-t-il ou reste-t-il stable ? S'il a grossi, regardez ce qui est entré, pas qui est lent.
A-t-on résolu au moins autant de bugs qu'il en est arrivé, par rapport à la période précédente ?
Le temps médian de correction a-t-il bougé ? S'il a bondi, trouvez le ou les deux bugs responsables.
Ouvrez le plus vieux bug. Corrigez-le, planifiez-le ou fermez-le avec une raison. Ne le laissez pas pour la semaine prochaine.
Regardez d'où viennent les rapports. Tout navigateur, appareil ou page qui pèse bien plus que sa part est une régression jusqu'à preuve du contraire.
C'est toute la revue. Elle tient dans un stand-up, elle n'a pas besoin de tableur, et elle répond à la seule question à laquelle le tableau de bord était censé répondre.
Dans BugDump, le bandeau de synthèse en haut de chaque tableau affiche ces quatre chiffres et se met à jour chaque minute.
Pour aller plus loin
De 40 rapports à 6 bugs – comment le tri devrait fonctionner — comment regrouper les doublons pour que quarante rapports redeviennent les six bugs qu'ils sont vraiment.
Trier les bugs plus vite avec un workflow au clavier — traiter une file de rapports sans lâcher le clavier.
Niveaux de priorité des bugs : pourquoi quatre choix figés ne collent jamais — pourquoi une échelle de priorité figée ne colle à aucune équipe, et comment définir la vôtre.