De la gestion de projet à la gestion de workflow

Il y a une chose qui me chiffonne lorsqu’on s’intéresse aux méthodologies agiles, telle qu’elles sont définies « by the book », ou telle qu’elles sont enseignées. On y décrit un fonctionnement à base de sprints de développement, qui s’enchaînent les uns après les autres, avec une durée de l’ordre de la…

Lire la suite

Les premiers enseignements de Rework

J’ai déjà parlé plusieurs fois de l’entreprise 37signals, de ses logiciels de gestion de documentation et de projet, et de sa méthode Getting Real. Actuellement, ses membres travaillent au successeur de leur livre, dont le nom sera Rework. Ils ont présenté quelques bribes d’information sur le livre, et je me suis arrêté sur le quatrième de couverture :

Je trouve que le texte qui s’y trouve est très intéressant, un brin controverse, et mérite qu’on s’y attarde. Voici une traduction très libre de son contenu, et ce que j’en pense.

“Dès que possible” est un poison

Il est vrai qu’en entreprise, on rencontre bien souvent ce genre de situation : On essaye de se mettre d’accord sur la spécification d’une nouvelle fonctionnalité, et quand vient le moment d’en définir la date de livraison, on se voit répondre “Dès que possible”. Cela peut sembler la réponse la plus honnête, la plus simple à comprendre de tous et la plus facile à gérer ; mais en fait il s’agit souvent d’un pis-aller qui démontre que le projet n’est pas réellement pris en main.

Quand on demande un développement ASAP (as soon as possible), on abdique sur tous les facteurs qui définissent un projet :

  • La définition exacte du projet n’a pas été faite correctement. On sait bien qu’on n’a pas pris le temps de réfléchir à tous les cas limites, à penser à toutes les situations. On sait − mais on ne le dit pas ouvertement − que les développeurs devront affronter tous ces culs-de-sac fonctionnels au fur et à mesure qu’ils se casseront les dents dessus, ce qui empêche d’apporter une quelconque valeur aux estimations qu’ils peuvent faire de leurs développements.
  • À partir du moment où la seule contrainte exprimée est celle du temps passé sur le projet, on accepte implicitement que des raccourcis soient fait pour atteindre l’objectif au plus vite. Un aspect en pâtira forcément, qu’il s’agisse de la qualité générale de la réalisation, de la maintenabilité du code, des tests, du débuggage, …
  • À l’inverse, l’absence de deadline réaliste autorise les développeurs à se lancer dans des développements inutiles (je ne parle même pas de ceux qui se tournent les pouces). On arrive ainsi à des situations où on découvre au bout de 2 semaines que le développement “ASAP” aurait pu durer 4 jours si on avait pris le temps de dimensionner et budgéter le projet correctement ; mais si on en fait la remarque au(x) développeur(s), on obtient une réponse du genre «Ah, moi j’estime que tout ce que j’ai fait était nécessaire pour que le projet fonctionne correctement. Il fallait me prévenir si c’était plus urgent que ça !».

Scrum : introduction

Scrum est une méthode de gestion de projet très intéressante. Pour mon premier article à son propos, je vais vous la présenter rapidement, et vous parler de l’un de ses concepts-clés : les sprints.

Scrum est une méthode agile qui ne se focalise pas spécialement sur les techniques de développement, mais plutôt sur l’organisation de projet et la gestion d’équipe. C’est une méthode moderne qui a fait ses preuves dans de nombreuses circonstances.

Présentation des rôles

L’image suivante présente d’une manière assez synthétique les différents rôles qui interviennent dans une équipe Scrum :

(image © Avangel, Wikipedia)

  • Le directeur de produit : Je préfère utiliser le terme de chef de projet fonctionnel. Son rôle est de présenter à l’équipe les fonctionnalités qu’elle devra développer, et de transmettre l’ordre de priorités. Il opère un suivi régulier avec l’équipe de développement, et remonte régulièrement les informations d’avancement au client.
  • Le Scrum Master : C’est un personnage très spécial qui prend en charge tous les aspects non techniques pour « protéger » l’équipe, particulièrement pendant les périodes de sprint (voir plus bas). Toutes les requêtes doivent passer par lui, pour s’assurer du respect de la méthode. C’est un rôle qu’on pourrait approcher de celui que je tiens – en temps que directeur technique – vis-à-vis de mes développeurs (hormis que je gère en plus des aspects techniques comme la validation des spécifications techniques).
  • L’équipe de développement : La théorie voudrait que l’équipe soit auto-gérée, et que ses membres prennent eux-mêmes leurs décisions de manière collégiale. D’expérience, j’ai rarement vu une équipe fonctionner correctement quand on la laisse faire ce qu’elle veut. Pour que ça fonctionne, il faut avoir des développeurs très compétents, avec de l’expérience, et surtout qui apprécie les contacts humains. Et malheureusement, toutes les équipes ont leurs stagiaires, leurs pas-très-bons-techniquement ou leurs autistes…

Les sprints

Au coeur de Scrum, il y a la notion de sprint. Le principe est de définir un lot de fonctionnalités à développer, puis de partir dans une phase de développement de durée « raisonnable » (2 à 4 semaines). Évidemment, l’ensemble des fonctionnalités doit avoir été prévu pour pouvoir être développé dans ce laps de temps.

L’important dans cet exercice, c’est de bien comprendre – et surtout faire comprendre aux autres acteurs – qu’une fois qu’on a défini la liste des fonctionnalités et qu’on a écrit les spécifications fonctionnelles, on entre dans une phase de quelques semaines pendant laquelle il est absolument interdit de changer les objectifs de développement. Cela a pour effet de pousser les clients à bien spécifier leurs besoins, car une fois que le sprint est lancé, il n’est pas possible d’ajouter de nouvelles fonctionnalités ni de changer l’ordre de priorité.

Test Driven Development

Je vous parlais récemment des tests unitaires. Je vous parlais entre autre de la difficulté d’imposer la discipline nécessaire à la réalisation de tests unitaires corrects et de leur maintien opérationnel.

Il existe une méthode de travail qui permet de forcer l’écriture des tests unitaires (tout au moins au début des développements). Il s’agit des développements guidés par les tests (ou Test Driven Development en anglais).
Cette méthode est toute simple à comprendre : Avant d’écrire un bout de code, on commence par écrire les tests qui vont vérifier la conformité du code.

Prenons l’exemple d’un code orienté objet. Imaginons que nous nous préparons à écrire une nouvelle classe.

  • On modélise l’objet, donc on connait ses méthodes publiques. On sait quelles entrées doivent produire quels résultats.
  • On écrit des tests pour vérifier les méthodes de l’objet.
  • On écrit le squelette de l’objet, avec juste les déclarations des méthodes.
  • On exécute les tests unitaires, qui tombent évidemment en échec.
  • On écrit le code de l’objet, en vérifiant que les tests passent un à un.

L’avantage avec cette manière de faire, c’est qu’au moment où le code est écrit, on est quasi-certain qu’il est conforme au comportement qu’on attend de lui. Pour peu qu’on ait pris soin de lancer régulièrement les tests unitaires au cours du développement, le code est rapide à valider.

Par contre, il va sans dire que si le TDD permet d’avoir des tests unitaires corrects pour de nouveaux développements, le problème reste entier pour l’évolution de code existant. La vigilance habituelle reste donc de mise, pour que les tests ne prennent pas la poussière. Mais il est possible de respecter cette démarche pour toutes les évolutions de code : On commence par modifier les tests unitaires existants, ou les compléter ; puis on effectue les développements qui valideront ces tests.

Mon expérience

Le TDD est ce que je qualifierais de vraie fausse bonne idée. En fait, j’ai vu plusieurs fois le même cheminement intellectuel être suivi par des équipes qui mettaient en place cette méthode :

Tests unitaires et intégration continue

Je vais vous parler de deux notions qui sont assez connexes, et que certaines personnes ont tendance à mélanger un peu.

Les tests unitaires

Le but des tests unitaires est d’automatiser les tests de non-régression. Quand on développe un logiciel, on peut facilement faire des modifications sans se rendre compte qu’elles introduisent des bugs dans certains cas particuliers. C’est ce qu’on appelle des bugs de régression, en ce sens qu’on introduit de nouveaux bugs à la suite d’une évolution fonctionnelle. Comme il n’est pas humainement possible de tester systématiquement tous les cas d’utilisation possible, ces bugs peuvent se retrouver déployés en production, avec tous les problèmes que cela comporte.

Une des notions importantes, quand on fait du développement, est de savoir que plus un bug est détecté tôt, plus il sera facile à corriger. Les gros soucis arrivent quand on fait du « sur-développement » par-dessus un bug de régression ; il devient très difficile de faire un retour en arrière sur le code incriminé, car cela impliquerait de supprimer des fonctionnalités. Il faut alors corriger ce nouveau code, en essayant de trouver une aiguille dans une botte de foin.

Concrètement, les tests unitaires consistent en un ensemble de scripts, qui ont chacun en charge la validation d’un morceau de code (ou d’une classe si vous faite de la programmation orientée objet). Il est assez évident de tester de la sorte les bibliothèques de fonction : les « librairies » peuvent être vues comme des boîtes noires, avec des entrées et des sorties. Il suffit d’injecter certaines données en entrée, et vérifier la conformité de ce qu’on obtient en sortie.
Pour du code applicatif, c’est un peu plus délicat, car on est parfois obligé de mettre en place un environnement de test sophistiqué (bases de données avec lots de test, génération de données aléatoires, gestion des tentatives de hack, …). Mais bien heureusement il existe de très nombreux frameworks pour vous aider à y arriver ; suivant votre plate-forme de développement, vous pouvez vous intéresser à JUnit (Java), SimpleTest (PHP), CppUnit (C++), JSUnit (Javascript), ASUnit (ActionScript), Test::Unit (Ruby), Test::Unit (Perl), unittest (Python), NUnit (.NET), …

Livre : Getting Real

Je vous ai déjà parlé de la société 37signals, au travers de ses outils Backpack et Basecamp. Je vais maintenant vous parler du livre qu’elle a publié en 2006 et qui contient toutes les règles de création et de gestion de projets web qu’elle applique en interne : Getting Real, The smarter, faster, easier way to build a successful web application.

Ce livre est disponible :

Le titre du livre est sûrement un gentil jeu de mots avec la très connue méthode Getting Things Done. Ce clin d’œil est une manière à peine déguisée de dire qu’il faut oublier toutes les méthodes existantes, faire table rase et suivre leur direction. Le livre décrit leur propre méthode agile, qui est censée s’appliquer à la réalisation d’applications web, mais peut être utilisée – au moins partiellement – pour d’autres types de projets ou d’organisations.

37signals

37signals a été fondée en 1999, exerçant une activité de web agency. Au cours des années, elle s’est fait connaître en publiant tout d’abord Basecamp, l’outil de gestion de projet utilisé en interne, puis le framework Ruby on Rails sur lequel Basecamp est basé. Depuis, 37signals a sorti plusieurs services en ligne, allant de la gestion de données jusqu’à la relation client, en passant par la messagerie de groupe. Leur blog d’entreprise, Signal vs Noise, qui parle aussi bien des outils édités par la société que de design et de développement web, est très connu et visité.

Les méthodes agiles

Cet article fait suite à ceux consacrés au cycle en V et au cycle itératif. Dans l’histoire des méthodes de gestion de projets informatiques, les méthodes agiles sont une évolution relativement récente qui tente de résoudre certains défauts des pratiques qui étaient en usage jusque-là.

Le manifeste agile

La définition de toutes les méthodes agiles est synthétisée par le Manifeste agile, qui a été rédigé en 2001 par plusieurs acteurs de ce domaine. Il distingue 4 valeurs fondamentales et 12 principes.

Les 4 valeurs

(traduction © Wikipedia et al)

  • L’interaction avec les personnes plutôt que les processus et les outils.
  • Un produit opérationnel plutôt qu’une documentation pléthorique.
  • La collaboration avec le client plutôt que la négociation de contrat.
  • La réactivité face au changement plutôt que le suivi d’un plan.
Les 12 principes

(traduction © Wikipedia et al)

  • Notre première priorité est de satisfaire le client en livrant tôt et régulièrement des logiciels utiles.
  • Le changement est accepté, même tardivement dans le développement. Les processus agiles exploitent le changement comme avantage compétitif pour le client.
  • Livrer fréquemment une application fonctionnelle, toutes les deux semaines à deux mois, avec une tendance pour la période la plus courte.
  • Les gens de l’art et les développeurs doivent collaborer quotidiennement au projet.
  • Bâtissez le projet autour de personnes motivées. Donnez leur l’environnement et le soutien dont elles ont besoin, et croyez en leur capacité à faire le travail.
  • La méthode la plus efficace de transmettre l’information est une conversation en face à face.
  • Un logiciel fonctionnel est la meilleure unité de mesure de la progression du projet.
  • Les processus agiles promeuvent un rythme de développement soutenable. Commanditaires, développeurs et utilisateurs devraient pouvoir maintenir le rythme indéfiniment.
  • Une attention continue à l’excellence technique et à la qualité de la conception améliore l’agilité.
  • La simplicité – l’art de maximiser la quantité de travail à ne pas faire – est essentielle.
  • Les meilleures architectures, spécifications et conceptions sont issues d’équipes qui s’auto-organisent.
  • À intervalle régulier, l’équipe réfléchit aux moyens de devenir plus efficace, puis accorde et ajuste son comportement dans ce sens.

Application concrète

Il existe plusieurs méthodes qui suivent l’esprit du manifeste. Elles ont chacune leurs spécificités, mais de manière globale elles œuvrent toutes dans les mêmes voies.

Le cycle itératif

Si vous avez lu mon billet sur le Cycle en V, vous savez pourquoi ce type de méthode de travail n’est pas adapté à la plupart des projets informatiques, qui réclament une plus grande souplesse. En l’appliquant de manière rigide, on finit par obtenir des logiciels mal adaptés (fonctionnalités sans priorités), livrés en retard (chaque étape bloque les suivantes) et souvent buggués (la technique se plie au fonctionnel).
C’est ainsi qu’est née la méthode du cycle itératif (ou incrémental), qui tente de formaliser une approche plus pragmatique et maniable.

Cycle itératif

Définition

Cette méthode se décompose en 6 étapes, dont 4 qui en constituent le « coeur » :

  • L’expression de besoin : Le client explique ce qu’il veut obtenir. On peut faire un parallèle avec l’étape de faisabilité du cycle en V, et dans une moindre mesure avec les spécifications fonctionnelles. L’idée reste que les informations en entrée peuvent être modifiées par la suite du processus.
  • Le coeur du processus itératif :
    • Spécification : C’est la traduction en langage technique des besoins fournis en entrée. C’est la réponse aux questions « qu’est-ce qu’on fait ? » et « comment on va le faire ? ».
    • Développement : Il s’agit de la réalisation concrète de ce qui a été défini.
    • Validation : C’est l’ensemble des tests qui permettent de s’assurer que le développement effectué correspond bien à ce qui était attendu.
    • Évaluation : Cette étape sert à effectuer un retour sur les écueils rencontrés et les fonctionnalités abandonnées pendant les 3 étapes précédentes, et l’utiliser comme informations d’entrée pour un nouveau cycle.
  • Déploiement : Les livrables qui ont été validés sont déployés pour que le client y ait accès.