jeudi 29 mars 2012

Comment se présenter en entretien

Comment se présenter en entretien et structurer son discours pour être clair et convainquant ? Telle est la question fatidique.
Depuis des années, l'entretien se déroule classiquement en trois parties, mais voyons ensemble les enjeux de chacune :
  1. Le recruteur présente la société, puis le projet.
    Le plus intéressant dans la présentation de la société relève des informations qui ne sont pas déjà disponibles sur le site web : organisation, culture, vision, méthodes.
    Au moment d'expliquer le projet, le recruteur oublie parfois d'expliciter la finalité du produit ou du projet, et rentre tout de suite dans les détails techniques. Or on ne peut pas comprendre l'architecture et la cartographie des composants et des flux d'un système sans connaître la nature de ses activités.
    Pendant ce temps, le candidat note tout ce qui lui permettra de faire un choix entre plusieurs opportunités le cas échéant, après la réunion. Il doit poser des questions pour éclaircir certains points, et ses questions auront pour effet de démontrer son intérêt pour le projet, ce qui est non seulement un élément indispensable pour rassurer un recruteur, mais aussi pour mieux préparer la suite de l'entretien et se distinguer.
  2. Le candidat présente son profil et son parcours.
    Le candidat fait une rapide introduction pour se présenter : qui est-il, son niveau de formation, son profil et ses atouts, des atouts et domaines de compétences qu'il devra mettre en relief en exposant son parcours.
    Pour un candidat qui recherche le poste auquel il aspire, au contraire du candidat qui doit gagner une mission pour la SSII dont il est salarié, le déroulement de la présentation est plus libre : il s'agit surtout de mettre en avant l'orientation qu'il souhaite donner à sa carrière, ses réussites professionnelles et ses choix de carrière passés, afin de déterminer si la société est en mesure de lui proposer le poste adéquat. Le candidat en SSII devra, lui, jongler entre l'obtention de la mission et ses intérêts propres, ainsi que le souci pour la SSII de garder ouverte la porte du client pour y placer d'autres consultants après lui, notamment s'il décline la mission.
    Pendant la présentation du projet qui a précédé, le candidat aura aussi noté dans un coin d'une feuille tous les mots-clés qui vont lui permettre d'adapter sa trame et d'orienter son discours, pour faire l'adéquation entre le poste proposé et ses compétences :
    • Réemployer oralement ces mots-clés afin d'y faire écho et déclencher un signal positif dans l'esprit du recruteur.
    • Passer rapidement sur les expériences qui ne sont pas significatives ou qui s'éloignent des préoccupations relatives au projet.
    • Insister sur les expériences révélatrices ou qui s'avèrent pertinentes dans le cadre du projet. Pour celles-ci, la méthode de l’entonnoir consiste à partir des généralités pour rentrer dans les détails :
      • présentation concise de la société,
      • le nom du département et sa taille, éventuellement lié à un produit,
      • l'équipe et sa taille, et le projet à sa charge,
      • Réalisations du candidat.
      • Ne pas oublier de citer les environnements techniques : méthodes de travail, technologies.
    • Tisser un fil directeur entre les expériences citées en ménageant des transitions : le candidat montre qu'il maîtrise son discours, est capable de prendre du recul, et garde l'attention du recruteur. Rien n'est plus fastidieux qu'une énumération, et ces transitions vont insuffler une dynamique au discours. Voici des éléments typiques d'une bonne transition :
      • Compétences développées ?
      • Compétences acquises ?
      • Ce que m'a apporté cette expérience ?
      • Ce que j'en ai retenu ?
      • "Le projet étant arrivé à terme", "Puis j'ai souhaité découvrir autre chose", etc, et on continue.
    • Lors de la conclusion finale, c'est le moment ou jamais de parler des points qui n'ont pas été abordés et qui peuvent valoriser la candidature, et lui donner un point d'orgue :
      • Projets personnels,
      • Blog professionnel,
      • Veille technologique,
      • Auto-formation,
      • Participation à des conférences publiques,
      • Ce qui vous intéresse dans le projet, le cas échéant,
      • Insister sur votre plus-value : ce que vous allez apporter à l'entreprise.
  3. Test technique, éventuellement, à réaliser dans un délai plus ou moins contraint.
  4. Si vous êtes présenté chez un client d'une SSII par un commercial, la phase de debriefing aura lieu sans vous : bilan sur la candidature, quelques questions-réponses pour lever des doutes persistants, TJM (tarif journalier moyen) de la prestation et négociation, date d'un retour pour communiquer la décision définitive, date de démarrage potentielle.
Remarques :
Aujourd'hui, des sociétés ont entrepris de demander aux candidats de se présenter en premier, afin d'éviter qu'ils n'utilisent la corrélation par mots-clés. C'est plus difficile, car le candidat doit se sentir prêt à prendre la parole dès le début de l'entretien et s'expose à un degré élevé d'incertitude. Or il a dû se déplacer pour arriver jusqu'aux locaux de la société, peut-être sort-il du métro (bruits tonitruants, odeurs nauséabondes, promiscuité excessive, chaleur étouffante, fatigue, sentiment d'oppression) et n'est-il pas vraiment dans les meilleures dispositions...
Mon point de vue est que le candidat ayant fait l'effort de venir jusqu'au recruteur, celui-ci devrait normalement témoigner d'une certaine courtoisie en ce sens.

Des SSII ont même institutionnalisé ce procédé, certaines sont sans doute conscientes d'avoir une image peu reluisante. Peut-être ne préfèrent-elles pas s'étendre sur la présentation de la société, qu'elles parviennent à éluder pour certaines d'entre elles. Quand je fais ce constat, pour ma part c'est rédhibitoire. Peut-être préfèrent-elles juger de la réaction du candidat, et voir quelles inflexions il va donner à sa présentation : affirme-t-il son projet professionnel, ou bien va-t-il le diluer dans des choix qu'il a dû subir, auquel cas on peut supposer qu'il est malléable, qu'il aura peu de revendications, voire qu'il sera facile de l'orienter, de l'influencer. Faute d'un objectif à atteindre, un candidat peut même en arriver à commettre des faux pas en se présentant. Faute d'un objectif à viser, il peut être tentant de se montrer le plus synthétique possible, mais en manquant d'évoquer certains traits qui vont révéler toute la qualité de son profil, un candidat risque indirectement de se dévaloriser et de jouer le jeu du recruteur au moment de la négociation des prétentions salariales.


Enfin, je dirais qu'il y a des jours avec et des jours sans, en dépit de votre préparation, sans compter qu'il faut savoir se garder une part d'improvisation, afin d'y gagner en spontanéité et vivacité : se sentir en danger est stimulant et pousse à se dépasser. Aussi je vous souhaite bonne chance et bon courage. Car, comme disait Louis Pasteur, "la chance ne sourit qu'aux esprits bien préparés".

Comment compter les lignes de code

En une seule ligne de commande dans un terminal Shell :
  • Pour compter le nombre de lignes de code en Java :
    find . -iname "*.java" -exec grep -E '^[.]*' {} \; | wc -l 
    find . -iname "*.java" -exec grep -vE '^[ ]*$' {} \; | wc -l sans ligne vide
    find . -iname "*.java" -exec grep -vE '^[ ]*($|//|/\*|\*|\*/)' {} \; | wc -l sans ligne vide ni commentaire
  • Pour compter le nombre de classes Java :
    find . -iname "*.java" | wc -l
Si le langage n'est pas Java, il suffit de changer l'extension.


Dans Eclipse IDE, c'est aussi possible, en sélectionnant une ressource dans la vue "Project Explorer", puis "Search" (Ctrl+H) :


La vue "Search" indique le nombre de lignes de code.

dimanche 25 mars 2012

[JUnit] Personnalisez vos tests avec @Rule

Les règles JUnit proposent un mécanisme d'extension du framework. Cette fonctionnalité permet de personnaliser le déroulement des tests :
  • vérifications supplémentaires des résultats,
  • préparation avant et nettoyage après,
  • rapports complémentaires.
Pour ce faire, il suffit d'ajouter un membre publique du type org.junit.rules.TestRule à la classe de test, et de l'annoter avec @org.junit.Rule :
public class MyTestCase {
    @Rule public TestRule myRule;
    ...
}


Règles proposées par JUnit

Pour le développeur, il est donc possible soit d'écrire ses propres règles à partir de l'interface TestRule, soit plus simplement de recourir aux règles proposées nativement par JUnit. Voici ce que propose le package org.junit.rules :
  • ExpectedException : cette règle permet de spécifier, à l'intérieur d'un test, le type et le message de l'exception attendue. Elle permet aussi de généraliser l'utilisation de @Test(expected=...) à une classe de test.
  • ExternalResource : classe de base pour toute règle qui doit préparer une ressource externe avant un test (fichier, socket, serveur, connexion à une base de données, etc), et garantir sa libération par la suite.
    • TemporaryFolder (dérivée de ExternalResource): cette règle permet d'inclure au test la création de fichiers et de répertoires temporaires, qui devront être supprimés à la fin de la méthode de test, que le test passe ou échoue.
  • RuleChain : cette règle permet de construire et d'ordonner une liste de règles.
  • TestWatcher : classe de base pour toute règle qui doit observer l'exécution d'un test sans en modifier les résultats.
    • TestName (dérivée de TestWatcher) : cette règle donne accès au nom du test à l'intérieur de la méthode de test.
  • Timeout : cette règle permet de spécifier le même délai d'exécution pour toutes les méthodes de test de la classe de test. Elle permet aussi de généraliser l'utilisation de @Test(timeout=...) à une classe de test.
  • Verifier : classe de base pour toute règle qui doit vérifier l'état d'un objet de test. Ce type de règle est susceptible de modifier le résultat du test.
    • ErrorCollector : cette règle permet de recueillir les échecs quand ils surviennent, sans interrompre le test. Le cas échéant, les échecs feront l'objet d'un rapport tout à la fin du test. Ça peut être utile lorsque les assertions d'un test sont indépendantes.

Règles personnalisées

Les classes de base ExternalResource, TestWatcher, et Verifier ont été ajoutées afin de faciliter et guider le développement de règles personnalisées :
  • ExternalResource propose d'implémenter des méthodes before() pour préparer des ressources et after() pour les libérer.
  • TestWatcher propose d'implémenter des méthodes :
    • starting() et finished() pour journaliser des informations avant et après le déroulement du test, quelle que soit son issue,
    • succeeded() et failed() pour journaliser des informations si le test réussit ou échoue respectivement.
  • Verifier propose d'implémenter une méthode verify() pour ajouter des vérifications au test.
Et pour qui veut écrire une nouvelle règle relative à un nouveau cas d'usage, l'interface TestRule comporte une unique méthode : Statement apply(Statement base, Description description);
base représente ici la méthode de test, et plus généralement encapsule une étape dans une suite de test : base.evaluate() pour l'exécuter,
description décrit le contenu du test et doit éventuellement servir à construire un message de log,
et où la valeur de retour du type Statement encapsule le traitement spécifique de la règle.

Remarque :
  • Avec les règles, il est possible de faire ce qu'il était déjà faisable dans les méthodes annotées par @Before[Class] et @After[Class], mais de manière plus efficace, et plus facile à partager entre projets : les TestRunners de JUnit reconnaissent intrinsèquement les TestRules, ce qui en fait un mécanisme d'extension naturel et privilégié de JUnit.
  • L'interface org.junit.rules.TestRule remplace l'interface org.junit.rules.MethodRule apparue avec JUnit 4.7 et rendue obsolète depuis la version 4.9 : la méthode apply a été simplifiée.

Code Source

Des exemples d'utilisation des règles JUnit sont proposés sur mon dépôt GitHub UnitTesting4Java, dans le module junit4-features (package xapn.testing.junit.rule).

vendredi 23 mars 2012

[Git] Visualiser l'historique

Il est facile de visualiser, grâce à git-log, l'historique des modifications en parcourant le graphe de Git, et de bien des manières, pour la branche courante, ou la branche indiquée le cas échéant.
  • git log équivalent à git log HEAD : affiche, pour chaque noeud, son SHA1, l'auteur, la date et le message.
  • git log -- <path> : affiche la même chose que précédemment pour chaque noeud ayant un impact sur le contenu de l'un des fichiers du répertoire indiqué.
  • git log --stat : affiche, en plus de git-log, la liste des fichiers modifiés pour chaque noeud, et en face de chacun d'entre eux, un aperçu quantitatif et qualitatif des modifications enregistrées.
  • git log -p : affiche, en plus de git-log, toutes les modifications de contenu pour chaque noeud.
  • git log --oneline : affiche, sur une ligne pour chaque noeud, le SHA1 abrégé et le message.
  • git log <since>..<until> : affiche tous les noeuds entre le noeud since exclus et le noeud until inclus. <since>..<until> peut être traduit comme le graphe incluant le noeud until et ses ancêtres, privé du graphe incluant le noeud since et ses ancêtres.
  • git log --graph : affiche tous les noeuds sous la forme d'un graphe. Pour un graphe (--graph) facile à lire (--oneline) incluant toutes ses références (--all --decorate) :
    git log --graph --oneline --all --decorate
  • git log --reverse : inverse l'ordre d'affichage de l'historique, du noeud parent vers le noeud enfant.
Par ailleurs, le plugin de Git pour Eclipse, EGit, propose de visualiser le graphe complet d'un dépôt grâce à la vue "History".

mercredi 21 mars 2012

Générer un matcher Hamcrest unifié

Hamcrest propose une alternative avantageuse aux assertions de JUnit, en fournissant une bibliothèque de matchers ou prédicats pour l'écriture de règles de correspondance de façon déclarative : en cas d'échec du test, le message est beaucoup plus explicite. Une autre qualité, qui a conditionné la viabilité du projet Hamcrest, est son extensibilité : il est facile de développer ses propres prédicats et Hamcrest les prendra en charge. Pour un usage plus aisé, il est même possible de générer un matcher unique à partir d'une multitude de matchers spécialisés, ce qui évitera les imports statiques à répétition.

Rompu à l'utilisation de JUnit, je ne me suis pas laissé facilement convaincre par le recours aux assertions fondées sur Hamcrest plutôt qu'aux traditionnelles assertions natives de JUnit, même si HamcrestCore est désormais embarqué dans JUnit. Peut-être à cause de l'obligation de choisir un matcher adéquat en fonction du type de donnée à vérifier, et d'écrire l'import statique correspondant. En ce sens, j'aurais tendance à préférer dorénavant FEST-Assert, qui se présente comme un DSL (Domain-Specific Language), plus intuitif.

Mais pour en revenir au sujet de l'article, j'ai récemment mis en oeuvre le générateur de code d'Hamcrest, et comme j'ai constaté quelques imperfections, j'ai dû trouver différents remèdes.

1) Prérequis : définition d'un prédicat personnalisé

Un prédicat personnalisé est déclaré sous l'une de ces formes :
  • public class MyCustomMatcher extends org.hamcrest.BaseMatcher {
        ...
    }
  • public class MyCustomMatcher extends org.hamcrest.TypeSafeMatcher {
        ...
    }
  • public class MyCustomMatcher {
        public static org.hamcrest.Matcher factoryMethodName(final ObjectToBeMatchedClass expected) {
            return new org.hamcrest.BaseMatcher() {
                private ObjectToBeMatchedClass theExpected = expected;
                ...
            }
    }
2) Génération d'un prédicat unique

Le générateur s'appuie sur un fichier de configuration XML listant les différents prédicats personnalisés à regrouper. A l'exécution, le générateur identifie par introspection la fabrique (factory method) grâce à l'annotation @org.hamcrest.Factory, et génère une classe unique de façade pour l'utilisation de tous ces prédicats. La signature de la méthode annotée par @Factory doit impérativement être de la forme :
public static Matcher factoryMethodName(...)

NB : Sans cela, si la signature devait avoir un autre type de retour, comme celui du matcher personnalisé (par exemple : "public static MyCustomConcreteMatcher factoryMethodName(...)"), alors le type en argument ObjectToBeMatchedClass ne serait pas reporté dans le code généré et n'apparaîtrait plus dans le prédicat de façade. De cela découleraient des warnings à la compilation, notamment dans les classes qui utiliseraient le prédicat de façade.

Résultat en console :

Generating xapn.testing.hamcrest.generated.MyMatchers
                       [T] is(Matcher p0)
                       [T] is(T param1)
               [Object] is(Class p0)
[OrdinarySystem] ready()
[OrdinarySystem] powerful()
[OrdinarySystem] lessOrdinary(OrdinarySystem thanAnother)
[OrdinarySystem] moreOrdinary(OrdinarySystem thanAnother)

Remarque : Le type en argument apparaît dans les logs entre crochets. Si la signature de la fabrique n'est pas correctement formatée, cela apparaîtra dans les logs de cette manière :
                         [] factoryMethodName()
Pour remédier à cet avertissement minimaliste dans le cadre d'une chaîne de génération avec Maven, il pourrait être de bon ton de développer un Mojo qui renverrait une exception du type org.apache.maven.plugin.MojoExecutionException, voire une MojoFailureException (échec du build dans le cas d'une release par exemple).

3) Invocation du générateur dans une chaîne de génération industrialisée

Le générateur peut être très simplement appelé en ligne de commande :
java -cp hamcrest-all-1.1.jar org.hamcrest.generator.config.XmlConfigurator $config-file $source-dir $generated-class $output-dir

Voici les arguments attendus, tels qu'ils sont explicités en ligne de commande  :
Args: config-file source-dir generated-class output-dir
config-file : Path to config file listing matchers to generate sugar for.
                  e.g. path/to/matchers.xml
source-dir  : Path to Java source containing matchers to generate sugar for.
                  May contain multiple paths, separated by commas.
                  e.g. src/java,src/more-java
generated-class : Full name of class to generate.
                  e.g. org.myproject.MyMatchers
output-dir : Where to output generated code (package subdirs will be
                  automatically created).
                  e.g. build/generated-code

Il faudra toutefois avoir déjà compilé les différents matchers listés dans $config-file, puisque le générateur est en fait alimenté par leurs binaires.

Hamcrest est aujourd'hui encore construit par Ant, aussi ce ne sera pas un problème d'ajouter une tâche Ant dans le processus de build d'un projet, afin de générer le code source du prédicat de façade et de le compiler ensuite. Cela donnerait une tâche Ant comme suit pour invoquer le générateur Hamcrest, suivi d'une tâche Ant pour compiler le code source généré :
<java classname="org.hamcrest.generator.config.XmlConfigurator"
    fork="true"
    failonerror="true"
    maxmemory="128m"
    >
  <arg value="${config-file} ${source-dir} ${generated-class} ${output-dir}"/>
  <classpath>
    <pathelement location="lib/hamcrest-all-1.1.jar"/>
    <pathelement path="${java.class.path}"/>
  </classpath>
</java>

Avec Maven, c'est encore plus simple, grâce au plugin org.codehaus.mojo:exec-maven-plugin. Si l’artéfact org.hamcrest:hamcrest-all fait partie des dépendances, toujours en ligne de commande cela donne :
mvn exec:java -Dexec.mainClass="org.hamcrest.generator.config.XmlConfigurator" -Dexec.args="$config-file $source-dir $generated-class $output-dir"

En revanche, dans le cadre d'un projet multimodule Maven, la démarche est un peu plus subtile. Typiquement, vous avez écrit vos matchers personnalisés dans un module dédié, et vous souhaitez pouvoir les utiliser dans vos tests dans des modules qui constituent votre projet. Pour obtenir une bibliothèque de matchers personnalisés, vous créez un module de type jar, et tirez une dépendance vers hamcrest-all, de scope compile. Dans les autres modules de votre projet, vous pourrez dorénavant dépendre de votre bibliothèque pour vos test, avec le scope test, de même qu'avec JUnit, TestNG ou Hamcrest. Rien de compliqué jusqu'à présent, seulement du classique.
Pour générer votre bibliothèque de matchers, vous allez en revanche devoir reproduire la démarche présentée avec Ant :
  1. compilation des matchers personnalisés,
  2. invocation du générateur Hamcrest,
  3. compilation du matcher de façade généré.
C'est là que ça devient problématique, étant donné que le cycle de vie Maven spécifique du type de package jar suit les phases suivantes dans cet ordre, sans qu'il soit possible de les répéter dans le même processus de build :
  • process-resources
  • compile : compilation des matchers personnalisés, à laquelle on ajoute l'invocation du générateur.
  • process-test-resources
  • test-compile
  • test
  • package
  • install
  • deploy
En l'état, le matcher de façade ne sera pas embarqué dans le JAR de l'artéfact final, faute d'avoir été compilé. Il faut donc choisir une solution parmi ces alternatives :
  • soit on développe un nouveau cycle de vie personnalisé : ça revient un peu à tuer une mouche avec un canon ;
  • soit on génère le matcher de façade dans un autre module : simple, expéditif, mais pas très élégant, car j'aurais voulu que tous les matchers soient empaquetés dans le même JAR pour faciliter la distribution de l'artéfact ;
  • soit on s'arrange pour tout faire rentrer dans la phase compile du processus de build de l'artéfact.
Sur internet, j'ai pu lire des posts où il était question de développer un Mojo, mais le problème lié au cycle de vie reste le même. Pour ma part, j'ai réussi à mettre en oeuvre la troisième option, en créant un profil Maven "hamcrest". Voici la définition de ce profil :
  • Profil désactivé par défaut.
  • Activation du profil si le code source à générer est absent.
  • Propriétés : arguments à fournir au générateur de code Hamcrest.
  • Plugin maven-clean-plugin / goal clean, attaché à la phase clean, pour supprimer le code source généré (dans le cycle de vie Clean de Maven).
  • Plugin maven-antrun-plugin / goal run, attaché à la phase compile, pour afficher un message echo en console contenant la valeur des arguments à destination du générateur de code Hamcrest.
  • Plugin exec-maven-plugin / goal java, attaché à la phase compile, pour invoquer le générateur de code Hamcrest.
  • Plugin maven-compiler-plugin / goal compile, attaché à la phase compile, pour forcer la compilation du code source généré.
Dès lors :
  • mvn clean install, pour laisser Maven activer automatiquement le profil "hamcrest".
  • mvn clean install -Phamcrest, pour forcer l'activation du profil "hamcrest".
Pour ne pas surcharger le contenu de cet article, je n'ai pas inclus le code source des matchers, ni les POM du projet de démonstration. Vous pouvez retrouver ce contenu dans son intégralité sur mon dépôt GitHub UnitTesting4Java : la bibliothèque des matchers personnalisée est "hamcrest-sugar-generation", et le matcher unifié est utilisé dans un test du module "junit4-features", dans le package "xapn.testing.junit.hamcrest.sugarmatcher".

4) Quelques conseils et astuces

Matcher Is :
Pour des raisons de commodité, pensez à toujours ajouter le matcher org.hamcrest.core.Is dans le fichier de configuration XML du générateur de code d'Hamcrest. Comme son utilisation est fréquente, cela vous épargnera d'ajouter un import statique dans tous vos tests pour un seul prédicat.
<matchers>

    <!-- Hamcrest library -->
    <factory class="org.hamcrest.core.Is"/>

</matchers>

Pourquoi un profil ?
Un profil peut comporter des clauses d'activation, ce qui, dans ce cas, évitera de lancer inutilement une génération à chaque processus de build. Par contre, il faudra penser à activer le profil suite à une modification des matchers personnalisés.

Quelle version d'Hamcrest ?
La version d'Hamcrest embarquée dans JUnit n'est pas la dernière, il y a même longtemps qu'elle n'a pas été mise à jour. Pour bénéficier de toute la variété des matchers développés par Hamcrest, il peut être utile d'ajouter la bibliothèque HamcrestAll dans ses dépendances.

Faciliter l'écriture des imports statiques dans une classe :
L'IDE Eclipse permet d'organiser automatiquement les imports statiques par autocomplétion, ou encore grâce au raccourci Ctrl+Shift+M. Pour que cela fonctionne également avec les matchers d'Hamcrest, il convient de modifier les préférences d'Eclipse : dans Java / Editor / Content Assist / Favorites, vous pouvez ajouter soit de nouveaux types ("New Type"), soit de nouveaux membres ("New Member").
Exemples de types intéressants à ajouter aux imports statiques automatiques :
  • org.hamcrest.CoreMatchers.* (hamcrest-core ou junit) : prédicats de base fournis par JUnit et issus d'HamcrestCore.
  • org.hamcrest.Matchers.* (hamcrest-all) : ces prédicats fournis par HamcrestAll réunissent les prédicats de base de HamcrestCore, également embarqués par JUnit, ainsi que des prédicats dédiés aux collections, aux textes, aux nombres et d'autres encore.
  • org.junit.matchers.JUnitMatchers.* (junit) : le prédicat de façade de JUnit agrégeant les prédicats internes de JUnit, ainsi que les prédicats d'Hamcrest embarqués par JUnit.
Hamcrest : org.hamcrest.CoreMatchers vs org.hamcrest.Matchers ?
Qui peut le plus peut le moins, et dans ce cas, Matchers recouvre CoreMatchers.

Contribution :
Hamcrest est aujourd'hui maintenu sous Google Code, et toute contribution devrait passer par la soumission d'un patch, à attacher à une issue existante... La question de faire passer le projet sous GitHub a été soulevée.

Liens :

mercredi 14 mars 2012

Techniques pour amener les équipes à l’excellence

Introduction

J'ai assisté mardi soir à la conférence du même nom animée à Paris par Michel Goldenberg. Le sujet principal était la maîtrise du degré de motivation d'une équipe de développement au cours du cycle de vie d'un produit logiciel. Si Scrum propose un cadre pour gérer le suivi d'un projet, il ne répond pas à la question des moyens dont peuvent disposer un Scrum Master et une équipe pour agir sur la motivation et les performances.

A l'opposé d'une attitude managériale du type "Command & Control", le manifeste agile privilégie l'auto-organisation des équipes et la responsabilisation de leurs membres : l'objectif commun est de fournir un logiciel qui fonctionne et utile pour les utilisateurs en respectant les délais. Cela part d'un bon sentiment, l'objectif est lui-même louable, malheureusement peut-on dire que le concept tiendra en haleine la motivation des développeurs, après des mois, voire des années à suivre le cérémonial de Scrum ? En pratique, que constate-on ? Et si la démotivation doit à terme gagner les esprits comme c'est le cas dans toutes les équipes de par le monde, comment peut-on y remédier ?

Je vais donc essayer de répondre à ces questions en quelques articles, en reprenant les informations échangées lors de cette conférence.