Il y a une limite à ce qu’on peut imposer

J’ai déjà écrit plusieurs billets consacrés à l’investissement personnel que l’on doit mettre dans son travail, que ce soit parce que les problèmes sont similaires malgré les différences d’échelle, ou parce qu’il y a toujours quelque chose à apprendre en entreprise, qu’il ne faut pas se sous-estimer, ou encore parce qu’il faut rester honnête en toute circonstance.

Comme je l’ai dit par le passé, il faut toujours chercher à progresser ; se mettre à la place des autres ; pensez aux choses auxquelles ils n’ont pas le temps de penser ; faire les choses qu’on est censé faire, pour leur éviter d’y penser à notre place ; apprendre de ses erreurs et ne pas y chercher d’excuse.

Je voudrais juste nuancer mon propos en disant qu‘il y a une limite à ce qu’on peut imposer aux autres.

Au sein d’une équipe

Cette limite est facile à atteindre quand on est « en bas » d’une hiérarchie, et qu’on tente d’imposer des solutions à ses supérieurs ou à l’ensemble du groupe. Le manque d’autorité empêche bien souvent de faire prendre aux autres le temps d’écoute et d’analyse nécessaire.

Mais cela peut aussi concerner des requêtes « top-down », qui peuvent être mal perçues car elles chamboulent les (mauvaises ou bonnes) habitudes.

Forcer les choses est la pire des démarches. Cela ne peut aboutir que sur des levées de boucliers.
Il vaut mieux adopter la technique du « courage, fuyons ! » :

L’encadrement des juniors

L’encadrement de juniors (stagiaires et jeunes diplômés) est un sujet assez vaste, et je vais juste aborder ici un point de détail qui concerne la manière dont les entreprises abordent leur productivité.

Il existe un principe de base qui est valable pour tout le monde :
« Comprendre ce qu’on fait et ce sur quoi on travaille »

Quand on embauche une personne qui a de l’expérience, c’est souvent pour la faire travailler sur des projets assez pointus. Dans ce cas, on s’attend communément à ce que la complexité de la tâche implique un « temps de démarrage » conséquent.

Il est assez logique que les juniors, pour leur part, se voient affecter des tâches plus accessibles d’un point de vue technique. Mais de nombreuses personnes voudraient qu’un junior soit immédiatement opérationnel. La réflexion qui est faite est du style : « Ce n’est pas bien compliqué, franchement, il devrait avoir terminé dans 2 jours, non ? ».
Le problème, c’est que n’importe quel travail doit se faire en ayant une maîtrise de son environnement et de ses impacts potentiels.

On ne peut pas demander à un jeune embauché de faire du bon boulot, si on n’a pas pris le temps de le former correctement sur les méthodes et outils spécifiques employés dans l’entreprise. Même si le travail demandé semble mineur, il faut se souvenir que l’expérience du collaborateur est limitée elle aussi. Un défaut d’encadrement peut conduire à des situations désagréables. La plus commune est que le junior, après avoir travaillé 3 jours sans avoir reçu de formation interne, doit recommencer tout le travail parce qu’il n’a pas respecté les directives qu’il n’a pourtant pas eues. On voit aussi fréquemment des personnes qui commencent à modifier du code sans le comprendre, générant un nombre incroyable de bugs de régression.

La pire situation que j’ai vue, c’est une entreprise qui formait ses jeunes « à la dure » : aucune formation, directement affectés aux débuggages ! Autant vous dire que ce n’était pas très efficace…

Si vous encadrez un junior

Vous devez lui fournir toutes les informations nécessaires. On ne laisse pas les gens se débrouiller tous seuls ; cela revient à les laisser dans la merde. Prenez le temps d’expliquer les méthodes, outils et usages qui ont cours dans votre entreprise. Faites leur faire un premier projet pour se faire la main, sur lequel vous les encadrerez de très près.

Le nocif

Dans la série des billets consacrés aux types de collègues, et pour faire la suite à ceux consacrés aux affectifs et aux revendicateurs, je vais aujourd’hui vous parler des « nocifs », c’est-à-dire des personnes qui – pour une raison ou une autre – sont réellement néfastes pour une équipe ou une entreprise. Nous allons voir comment reconnaître un nocif, et quelles sont les solutions qui s’offrent à vous pour traiter leurs cas.

À quoi reconnaît-on un nocif ?

Nous avons tous cotoyé au moins une personne dont le comportement ne semblait pas correspondre à celui attendu. Cela peut toucher un assez grand nombre d’attitudes :

  • Connaissances techniques trop faible. Un développeur qui est tellement mauvais techniquement qu’il produit systématiquement du mauvais travail.
  • Problèmes d’horaires. Quelqu’un qui arrive à 11h00 le matin et part à 17h30 le soir, ou qui se prend 20 minutes de pause toutes les 45 minutes.
  • Non-implication dans son travail. Une personne qui se met dans un simple rôle d’exécutant, au lieu d’utiliser ses compétences et son imagination pour faire réellement avancer ses projets.
  • Mauvaise volonté systématique. Quelqu’un qui réfute par principe toutes les idées qui lui sont soumises, ou qui ne prend en compte que les choix qui l’arrangent.
  • Problèmes de communication. La personne qui reste dans son coin en parlant le minimum possible. La personne qui n’arrive pas à avoir un débat constructif, et s’énerve dès que ses idées ne sont pas suivies. Celui qui ramène toutes les discussions à ses propres problèmes immédiats.
  • Problèmes avec l’autorité. Quelqu’un qui n’accepte pas qu’une autre personne puisse décider de ses priorités et de son planning.
  • Comportement non professionnel. Une personne qui se permet d’insulter ses collègues. Un commercial qui tutoies les clients. Un chargé de clientèle qui n’offre pas toute l’écoute qu’li devrait.

L’honnêteté paye toujours

L’honnêteté est généralement considérée comme une qualité humaine. Mais bizarrement, ce n’est pas une vertue très courante dans le monde professionnel.

Pourtant, c’est une approche qu’il faut chercher à avoir, car elle facilite grandement le travail, aussi bien quand on parle du boulot d’un développeur que de l’image d’une entreprise.

Au niveau individuel

Quand on commence à travailler, quelle que soit la branche, on a tendance à prendre assez mal les critiques. C’est le syndrôme du « petit enfant pris en faute » ; on s’en veut énormément, on a l’impression d’être en dessous de tout, et parfois on devient rouge pivoine. Avec le temps, on apprend à prendre sur soi, à faire la part des choses ; on arrive à comprendre les remontrances et à les intégrer pour progresser professionnellement, sans pour autant que cela devienne un traumatisme.
Mais cela peut avoir aussi un effet pervers. Quand on est un débutant, on remet peu en cause les remarques qui nous sont faites. Plus on progresse, plus on se sent à l’aise, et plus notre expérience professionnelle nous fournis des « armes » qui nous permettent d’embobiner nos interlocuteurs.

Combien de fois ai-je vu des gens expérimentés qui, lorsqu’ils se prenaient une remarques parce qu’ils avaient mal fait leur boulot, tournaient autour du pot pendant des heures, à expliquer pourquoi les choses s’étaient mal passées, que ce n’était pas de leur faute, qu’ils attendaient quelque chose d’un collègue, que c’était forcément un concours de circonstances, qu’il fallait incriminer les tâches solaires et les phases de la lune !
À chaque fois, il aurait été plus simple, plus rapide et plus professionnel, de répondre simplement « Ah oui, c’est ma faute. J’ai oublié tel truc ou j’ai mal fait telle chose ».

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 :

Gestion de sources, versions de logiciels

Lorsqu’on développe un logiciel, il est absolument nécessaire d’utiliser un outil de gestion de sources. Évidemment, il serait possible de stocker ses fichiers dans un répertoire. Mais si vous voulez travailler sérieusement, vous aurez besoin de stocker les différentes versions de vos sources, pour suivre leur évolution au fil du temps ; et si vous travaillez à plusieurs sur le même projet, cela devient impossible.

Les logiciels de gestion de sources permettent à plusieurs personnes de travailler sur les mêmes fichiers, chacun dans leur coin, puis de tout rassembler pour obtenir une version continuellement à jour des sources. Ils apportent des fonctions permettant de définir des versions globales. Il existe un grand nombre de ces systèmes :

  • Les ancêtres RCS et CVS ont laissé la place à Subversion, qui offre des fonctionnalités supplémentaires bien appréciables. Ce sont des systèmes centralisés faciles à appréhender et à installer, et sont sous licence libre.
  • De nouveaux système sont apparus, basés sur un modèle décentralisé. Parmi ceux-ci, ont peut noter que les plus connus dans le monde de l’open-source sont Bazaar (sponsorisé par Canonical, à l’origine de la distribution Linux Ubuntu), Git (utilisé pour le noyau Linux) et Mercurial.
  • Du côté des logiciels propriétaires, les plus connus sont Visual SourceSafe de Microsoft et BitKeeper (qui a été utilisé pour le noyau Linux jusqu’en 2005).

Je vais vous présenter l’utilisation de ces outils, en utilisant l’exemple de Subversion (SVN en abrégé) car c’est le système de plus répandu et celui que j’utilise ; mais ces concepts sont toujours valables.

Principes généraux

Gestion basique

A la base, les sources d’un projet sont disponibles sur la branche principale (trunk). Les développeurs y récupèrent les sources (checkout) sur leur propre environnement de travail, et y ajoutent leurs versions modifiées (commit).

SVN - checkout - commit

PlanZone

Augeo est un éditeur de logiciels parisien, spécialisé depuis plus de 15 ans dans les logiciels de gestion de projets et de portefeuilles de projets. En 2008, cette entreprise a lancé PlanZone, qui est un outil de gestion de projet collaborative sur le Web. Évidemment, ce logiciel entre en concurrence avec la référence du secteur (Basecamp), mais aussi avec les autres challengers (tel que Taskii). Nous allons voir comment il se défend.

Création de projet

La découverte de PlanZone est facilitée par un assistant qui vous guide dans la création d’un premier projet. C’est le premier logiciel de ce type qui me propose de choisir parmi plusieurs modèles de projet, ce qui a une influence sur les étapes de réalisation et le type de tâches à gérer.

Bizarrement, chaque projet doit avoir une date de début et une date de fin.

Information importante : Il est possible de créer un projet en important un fichier Microsoft Project. Je n’ai pas essayé cette fonctionnalité, mais j’imagine que cela doit être pratique pour les équipes qui veulent migrer vers une solution plus agile et collaborative.

Notions et fonctionnalités

Il y a plusieurs aspects qui interviennent dans l’utilisation de PlanZone :

  • L’unité de base est le projet. Comme je le disais plus haut, un projet a un titre, une description, une date de début et une date de fin. Le terme activité est aussi utilisé comme synonyme (c’est assez déstabilisant au début).
  • Un projet peut contenir des sous-activités, qui peuvent elles-mêmes avoir des sous-activités (le tout organisé de manière hiérarchique). On se retrouve donc à gérer des « activités » au sens large, qu’on peut assimiler à des projets et des sous-projets.
  • Une activité peut contenir :
    • des sous-activités (je viens de le dire) ;
    • des ressources, c’est-à-dire des personnes qui vont pouvoir intervenir sur les tâches, avec éventuellement un décompte du temps passé ;
    • des jalons, qui comportent un titre, une description, et une date prévue d’accomplissement ;
    • des tâches, qui comportent un titre, une description, une date butoir, une priorité (basse/normale/haute), et peuvent être affectées à des utilisateurs ou des groupes d’utilisateurs ;
    • des discussions, qui affichent les messages en ordre inversement chronologique (les plus récents en premier).

Affichages des informations

Une vue synthétique présente les principaux aspects d’un projet : le pourcentage de sa réalisation et de celles de ses différents jalons, et la liste des discussions qui s’y rapportent.

La grande force de PlanZone, c’est la vue par diagramme de Gantt. C’est une fonctionnalité très rare dans les logiciels de ce type, ce qui est bien dommage.

(image © planzone.com)

Elevator Pitch

Il existe un concept très intéressant, assez connu chez les américains : le « elevator pitch ».

L’idée est simple à comprendre. Imaginons que vous ayez créé une start-up, et que vous passiez du temps à un salon pour trouver un investisseur ; bizarrement, c’est après une longue journée infructueuse que vous allez croiser un important VC, dans l’ascenseur qui vous ramène à votre chambre d’hôtel. Ou encore, vous êtes un développeur ambitieux, et vous cherchez à présenter un projet personnel au big boss de votre compagnie ; et c’est près de la machine à café que vous tombez sur lui de manière imprévue. Ou vous souhaitez conclure un gros contrat avec un client important, mais vous êtes bloqué par son directeur commercial ; là encore, ce PDG fera un jour son footing dans le même parc que vous sans que vous l’ayez prévu.

Ce genre de situations ne semblent pas si inhabituelles qu’il n’y paraît. Une quantité non négligeable de contrats se signent de cette manière.

En quoi ce concept est-il intéressant ? Eh bien parce qu’il faut être préparé à ces situations. Dans ces conditions, le but est d’éveiller l’intérêt de l’interlocuteur, de l’accrocher pour qu’il ait envie d’en savoir plus. Et cela en quelques dizaines de secondes. Cela force à aller à l’essentiel.
Être enfermé 45 secondes avec quelqu’un oblige à synthétiser ses idées, à partager une vision large des choses (celle qui est intéressante !).

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), …