Estimations et planning

Publié le 10 février 2008 par Carlseleborg
Pour un éditeur de logiciels, savoir prévoir avec un minimum de certitude la date de sortie d'une prochaine version ou mise à jour présente un intérêt sur le plan commercial aussi bien que financier. Toute entreprise a un budget à gérer, et il est vital d'avoir un bon aperçu des moments où l'on peut attendre des rentrées d'argent.
En termes de développement d'un produit logiciel, cela revient à dresser la liste des fonctionnalités à implémenter ou à améliorer, à estimer le temps de travail nécessaire pour chacune d'elles et à faire le total du tout pour obtenir une date de sortie possible.
Notez bien: il y a un piège dans le choix du mot "développer". Pour moi, cela comprend les tests et le débogage, ces deux phases-là prenant la plupart du temps plus de temps que l'implémentation elle-même. Mais oui, Madame!

Estimations et planning chez Ableton

Au Royaume d'Ableton, chaque Maître Développeur doit estimer lui-même le temps qu'il lui faut pour une fonctionnalité donnée. A partir de ces estimations, un planning de sortie est établi, qui doit être validé par le Grand Argentier, qui sait combien de temps le Royaume peut tenir sur ses réserves accumulées lors de la dernière sortie. Bien sûr, comme avec tout projet logiciel, il y a des retards. Le génie des Gardiens du Planning est de considérer ces retards comme des faits (et non comme des erreurs et un coupable à écarteler sur la place publique) et de décider s'il faut repousser la date de sortie, ou s'il vaut mieux laisser tomber la fonctionnalité, cette dernière décision étant toujours prise avec l'accord du Conseil Suprême des Spécifications.
Le développeur découpe donc sa fonctionnalité en sous-tâches, plus faciles à estimer, chacune représentant moins de 16 heures de travail.
Je prends un exemple: avec Live 7, nous avons introduit de nombreux instruments et extensions sous forme de contenu, et chacun vient avec son numéro de série, si bien qu'un utilisateur qui achète Ableton Suite se retrouve avec 9 numéros de série. Avec la version 6 il aurait fallu les entrer les uns après les autres pour tout débloquer ; Live 7 contacte Ableton.com lorsqu'on entre le premier numéro, reçoit automatiquement tous les autres, et propose à l'utilisateur de tout débloquer d'un coup de cuiller à pot. En interne, nous avons nommé cette fonctionnalité UnlockLicense, car elle permet de débloquer toute une licence grâce à un seul numéro de série.
Peut-on en estimer correctement le temps nécessaire pour la tâche "Implémenter UnlockLicense"? Un peu de code réseau, quelques modifications de code de gestion des licences, une ou deux fenêtres de dialogue, allez... hmmm, on va dire 20 heures, 22 à tout casser. Il y en a un peu plus, je vous le mets quand même?
Bien sûr, une telle estimation ne vaut rien. Il faut avoir déjà réfléchi au problème pour savoir exactement ce qu'il y a à faire:
  • Création d'une requête HTTP
  • Connexion synchrone avec le serveur et réception du résultat
  • Décodage du résultat
  • Traitement de chacun des 7 cas d'erreur possibles
  • etc...
Voilà des tâches plus simples à estimer. "Création d'une requête HTTP": 2 heures, refactorings et tests unitaires compris.
Pour des raisons de comptabilité, chaque développeur doit également enregistrer combien de temps il passe sur chaque tâche, les tâches appartenant à des projets différents qui doivent être comptabilisés différemment. En plus, il faut pouvoir connaître l'état d'avancement d'une fonctionnalité. Nous voilà donc avec deux données à récolter pour chaque tâche: 1) une estimation du temps nécessaire, et 2) une mesure du temps réellement passé.
Nous utilisons pour cela un petit outil interne, la Todo List, qui permet d'entrer les tâches et de donner une estimation pour chacune d'elle. L'outil permet aussi de chronométrer le temps passé à travailler sur chaque tâche.

A la recherche du temps perdu

Je décidai de m'intéresser au sujet après avoir lu plusieurs articles là-dessus. Je commençai à dresser des listes de tâches et à enregistrer le temps passé sur chacune d'elle, puis je comparai le résultat à mon estimation initiale - en général, je calculais un total en heures que je divisais par 8 pour obtenir une estimation en jours.
L'un de mes premiers constats fut que je ne travaillais pas 8 heures par jour. Surprise! Bien que je passais 8 heures au bureau, mon temps de travail effectif était plutôt, coïncidence étrange, de 5 heures. Le reste: réunions, cafés, furetage sur Internet, administration, etc. il est vrai que si je travaille en général plutôt bien, je travaille lentement, et il y a sans doute beaucoup de gens qui tournent plutôt autour 6 heures par jour (pour 8 heures de présence), mais personne ne passe 100% de son temps au bureau à produire.
Une fois cet ajustement fait, je me retrouvai confronté à un autre problème: celui de tout comptabiliser... et aussi le reste! Ainsi, la durée d'une tâche de développement peut comprendre, en plus du temps de codage: spécification, prototypage, débogage, tests, mais aussi réunions, vacances, pannes informatiques, grèves, arrêts maladie, etc. Les premiers rallongent le temps qu'il faut pour terminer une tâche, les seconds diminuent le temps qu'on peut y passer sur une période de temps donnée.
Ces paramètres désormais pris en compte, il ne restait plus qu'une chose à peaufiner: la qualité de l'estimation elle-même. Lorsque j'ai commencé à utiliser la Todo List chez Ableton, le Maître du Planning m'a expliqué qu'il fallait mettre à jour l'estimation si le temps passé sur une tâche dépassait la première estimation. Ce que je fis pendant longtemps. Sauf que cette approche à un problème: si elle permet de corriger la date prévue de fin d'implémentation, elle ne permet pas de mesurer la qualité de l'estimation, puisque le temps estimé finit toujours par être très proche du temps passé.
Or ce qui intéresse votre serviteur, c'est d'améliorer ces estimations. J'ai donc eu une autre idée: lorsqu'une tâche vient tout juste de dépasser le temps estimé, je crée désormais une nouvelle tâche, avec le même nom, mais avec un petit numéro entre parenthèses. Par exemple:
  • Connexion synchrone... [Estimé: 3 heures, passé: 3h20]
  • Connexion synchrone... (2) [Estimé: 2 heures, passé: 2 heures]
Ayant sottement (mais humainement) oublié la version Mac OS de cette partie du code, hop! voilà 2 heures en plus à glisser dans ma liste. Avec cette méthode, on voit très bien ce qui s'est passé: en tout, la tâche à duré 5h20 alors que mon estimation d'origine était de 3 heures, mais l'estimation finale est correcte à 20 minutes près. Comme les deux tâches appartiennent au même projet, le résultat final reste bon.
Ainsi, lorsqu'une fonctionnalité est terminée, je peux revenir sur mes enregistrements et analyser la qualité de mes estimations. Les dernières mesures ont montré que je suis un indécrottable optimiste, car mes estimations ne représentent en moyenne que 80% du temps réel. Comme au lycée: sérieux, mais peut mieux faire.

Spolsky Based Scheduling

La source la plus intéressante à mon sens sur l'estimation du temps, c'est Joel Spolsky. Dans son produit phare, FogBugz, un outil de gestion de projets, il a poussé l'estimation du temps plus loin: plutôt que de produire une date de sortie figée, FogBugz prend en compte les erreurs d'estimations de chacun pour produire une courbe indiquant la probabilité de sortir le logiciel avant tel ou telle date. Il appelle sa méthode Evidence Based Scheduling, soit pour Molière: la gestion du temps basée sur les faits.
Voici trois de ses articles sur le thème de l'estimation. Ils sont tous intéressants, y compris le premier, malgré le petit encart qui indique que l'article est obsolète.
Bonne lecture!