Skip to content

Latest commit

 

History

History
893 lines (665 loc) · 38.5 KB

chapitre 12.adoc

File metadata and controls

893 lines (665 loc) · 38.5 KB

Chapitre 12

L’assurance qualité

Une application qui fonctionne, c’est bien. Mais du code qui est correctement construit, évolutif, lisible, maintenable, c’est mieux. L’assurance qualité est un exercice délicat qui tente de canaliser la créativité débordante des développeurs pour éviter l’anarchie sans pour autant restreindre leur productivité ou leur capacité d’innovation. Maîtriser un projet, c’est aussi savoir en extraire les indicateurs de qualité adéquats et se donner les moyens d’en suivre l’évolution.

Audit de code

Lors de notre intégration au sein de Geegol, notre projet a subi les regards inquisiteurs de ceux qui allaient devenir nos collègues. Habitudes différentes obligent, certaines tournures de notre code ne collaient pas avec la culture locale. Si la qualité d’un projet était évaluée sur des critères purement subjectifs de ce niveau, nous serions bons pour une réécriture complète, coûteuse et probablement inutile. Par contre, certains aspects de notre projet mériteraient peut-être une analyse plus minutieuse – nous ne pouvons pas être experts en tout !

Les outils d’audit de code ont l’intérêt d’être objectifs. Bien sûr, les règles qu’on leur demande de vérifier ont été choisies et pondérées selon des critères propres à l’entreprise, mais au moins elles sont clairement identifiées et justifiées. Si le groupe a fait le choix de mettre l’accent sur la qualité de documentation, il poussera au maximum les métriques concernant la Javadoc et le nombre de lignes de code sans commentaire. Cela ne garantit en rien un code bien documenté, mais cela donne tout de même une indication à partir de laquelle on peut travailler.

Les outils d’audit sont légion, et ils produisent des rapports plus ou moins complexes à analyser (du moins pour un développeur lambda). Le monde open-source en fournit une jolie panoplie, dont le seul défaut est de ne pas être intégrée. Chaque outil va produire un rapport, dans un format propre, qu’il nous faudra éplucher.

Par ailleurs, l’intérêt de ces outils n’est pas de faire des audits ponctuels pour donner une note à une équipe de développement. Si on en arrive là, c’est qu’ils sont utilisés bien trop tard. Leur plus-value apparaît dans les indicateurs synthétiques qu’ils fournissent et qu’on peut suivre au cours de la vie du projet dès que du code est écrit, signalant ainsi toute dérive malheureuse dans les bonnes pratiques de développement.

MangaVincentM

Vincent s’attaque à outiller notre projet pour répondre au mieux aux attentes du groupe. Il épluche la longue liste des outils disponibles pour en tirer le meilleur et proposer une boîte à outils conviviale et pertinente. Son objectif est de démontrer notre capacité de réaction, avant que la cellule qualité ne rende son verdict après dix jours d’audit de notre code. Pour chaque problème identifié, il veut être capable de répondre :

·     que nous l’avons également identifié, éventuellement avec un poids différent, et sommes donc tout à fait en mesure de le traiter ;

·     que nous disposons de l’outillage nécessaire pour nous assurer qu’il ne se reproduise plus ;

·     que nous sommes en mesure de fournir des indicateurs démontrant l’amélioration progressive de notre code sur la base des critères identifiés par les responsables qualité.

Avec un dossier de défense aussi bien ficelé, nous devrions en principe éviter de voir trop de monde fourrer son nez dans notre code et nous prendre de haut pour nous expliquer comment bien travailler. Nous avons tout de même notre fierté, et noubliepaslalistedescourses reste notre bébé !

Analyse statique

Une première catégorie d’outillage concerne l’analyse statique du code. Il s’agit d’une relecture du code par un outil qui va rechercher des patrons particuliers et calculer des métriques. En Java, il existe plusieurs outils de cette catégorie, lesquels peuvent extraire :

·     une liste d’alertes signalant des mauvaises pratiques connues, tournures de code maladroites ou bogues récurrents liés à l’imperfection des développeurs qui tombent tous dans les mêmes pièges – et aucun de nous ne fait exception à ce constat ;

·     des indicateurs sur la structure du code, jugeant sa modularité, sa complexité ou son niveau d’abstraction.

Le premier type d’indication est évidemment celui qui attire tout de suite nos décideurs : comment résister à un outil qui, en quelques clics, va identifier tous les bogues si coûteux que nous avons négligemment laissés traîner ?

Checkstyle

MangaVincentM

Vincent expérimente tout d’abord un outil open-source de cette catégorie sur notre code : Checkstyle. L’analyse est de niveau syntaxique et signale les incohérences qui existent dans notre façon de travailler. Une grande partie des règles de Checkstyle concerne le formatage du code plus que son fond, l’outil semble donc à la fois tatillon et sans grand intérêt.

MangaVincentS

L’autre Vincent – si vous avez bien suivi les chapitres précédents, vous aurez noté que notre équipe compte deux Vincent ;) –, qui suit de loin le travail de son collègue par pauses-café interposées, n’est pas de cet avis. Il a passé deux heures à fusionner ses dernières modifications avec celles d’Hervé, non pas parce que ce dernier travaille comme un cochon (sans quoi, il ne serait pas dans l’équipe !), mais tout simplement parce qu’il utilise des règles de formatage de code différentes (voir Listing 12.1).

Listing 12.1 : Comparaison de nos conventions de formatage du code

$ deux colonnes côte à côte$

$ 1ere colonne $MangaVincentS  

public class ListeDesCourses implements Data \{

   private Set courses = new HashSet();

 

   public void addCourse(String course) throws IllegalStateException \{

          courses.add(course);

   }

 

   public Collection getCourses() \{

          return courses;

   }

$ 2^e^ colonne $MangaHervé

public class ListeDesCourses

    implements Data

\{

    private Set courses = new HashSet();

 

    public void addCourse( String course )

        throws IllegalStateException

    \{

        courses.add( course );

    }

 

    public Collection getCourses()

    \{

        return courses;

    }

La différence entre ces deux fichiers sources est minime, cependant les outils de fusion automatique ne savent pas la gérer et obligent Vincent à vérifier ligne par ligne la concordance des deux versions concurrentes.

L’homogénéisation, surtout si elle est poussée à outrance, peut être ressentie parfois comme une façon de brider l’appropriation du code par les développeurs. Vouloir que tout le monde travaille strictement de la même façon c’est, en effet, faire de nous de simples machines à coder sans liberté individuelle. Par contre, laisser chacun faire ce qu’il veut à sa sauce n’est pertinent que si cela ne vient pas perturber les autres. Pour faire intellectuel, disons que "la liberté des uns s’arrête là où commence celle des autres".

Même si cela va nécessiter de se poser pendant une heure et obliger certains d’entre nous à accepter un formalisme qu’ils n’apprécient pas forcément, se mettre d’accord sur des règles de ce type économisera à chacun de longues heures d’un travail inutile, rébarbatif et source d’erreurs. Sans compter que notre IDE préféré sait nous aider à formater le code à la volée !

Les règles, même les plus superficielles, de Checkstyle ont donc leur rôle. L’analyse du code signalera directement que le petit dernier arrivé dans l’équipe ne respecte pas nos règles communes et va à un moment ou un autre provoquer le problème rencontré par Vincent et Hervé.

Checkstyle compte également de nombreuses règles qui valident le niveau de documentation technique du code. Ici aussi, pas de règle générale : du code peut être lourdement commenté et totalement incompréhensible, le commentaire peut d’ailleurs être totalement obsolète, et du code sans commentaires est parfois extrêmement limpide et ne nécessite aucune explication complémentaire. Cependant, si nous définissons un niveau de documentation que nous considérons souhaitable pour notre projet, Checkstyle saura indiquer nos points faibles ou notre relâchement.

Enfin, Checkstyle propose quelques règles plus techniques sur l’utilisation des mots clés et des structures de code. Une fois encore, la sélection de ces règles et leur pondération sont un travail que nous devrons affiner au fur et à mesure de notre utilisation de l’outil. Activer toutes les règles n’apporte rien, l’information étant noyée dans la masse. C’est même contre-productif, puisque ça amène à penser que l’outillage est inutilisable car trop tatillon.

FindBugs

MangaVincentM

Vincent poursuit son expérimentation sur l’analyse statique du code avec FindBugs. Comme son nom l’indique, cet outil se propose de trouver tout seul les bogues dans notre code, lesquels correspondent à des patrons de codage fragiles et à éviter. Même si un développeur expérimenté en est conscient, il risque de les mettre en œuvre par mégarde.

Plutôt que de le considérer comme un juge intransigeant, il faut voir FindBugs comme un conseiller qui cumule la connaissance des erreurs réalisées par des centaines de développeurs et est capable de les identifier. Sa base de données de choses à ne pas faire se distribue entre mauvaises pratiques, défauts de performances, dysfonctionnements, incompatibilité avec un mode multithreadé et problèmes de sécurité.

Une fois de plus, activer toutes ses règles sans se soucier du contexte risque surtout de produire un rapport de milliers de lignes à peine exploitable. C’est à nous de comprendre chacune de ses règles, de voir si elle s’applique à notre projet et l’importance que nous lui donnons. La simple lecture de ces règles est d’ailleurs très formatrice !

Nous pouvons également assister FindBugs dans son travail d’analyse pour le rendre plus pertinent. Des annotations comme @NonNull peuvent être ajoutées dans le code pour préciser, par exemple, qu’une méthode n’accepte pas un appel sans un paramètre correctement renseigné (fonctionnalité qui est d’ailleurs proposée pour Java 7). La présence de cette annotation permet à l’outil de contrôler tous les endroits où elle est invoquée et, en même temps, complète la documentation de notre code en précisant nos intentions.

De la même façon, FindBugs peut exploiter les annotations définies en marge du livre Programmation concurrente en Java, de Brian Goetz – chez le même éditeur, excellent ouvrage que je vous recommande ;) – pour identifier les problèmes de gestion concurrente en environnement multithread.

PMD

MangaVincentM

Vincent termine son tour d’horizon en installant un autre outil d’analyse statique : PMD. Celui-ci se place à mi-chemin entre Checkstyle et FindBugs. Moins formel que Checkstyle, il ne propose pas des règles aussi poussées que FindBugs (aidé par des annotations). Cela ne signifie pas pour autant qu’il soit inutile. Il vient renforcer la pertinence de l’analyse en proposant un autre regard sur notre code.

Il nous reste cependant à définir soigneusement ses règles d’analyse pour qu’elles soient cohérentes avec nos deux autres outils !

Analyse dynamique

Les outils d’analyse statique font déjà de grandes choses mais ils ne peuvent pas faire de miracle. En particulier, ils ne sont pas en mesure de deviner comment est utilisée réellement l’application. Pour cela, il faut la faire tourner dans un environnement et une utilisation réalistes. Or, nous avons déjà, depuis le Chapitre 4, une belle panoplie de tests qui exécutent notre application, par petits morceaux, en se focalisant sur des scénarios d’utilisation issus de nos besoins fonctionnels (rappelez-vous les règles du développement dirigé par les tests !).

Cobertura, Clover ou Emma sont des outils d’analyse dynamique qui visent à déterminer quelle portion de notre code est exécutée au cours de nos tests, censés couvrir les fonctionnalités de notre application. Leurs rapports indiquent le taux de couverture du code et remontent jusqu’au code source pour nous indiquer quelle ligne a été exécutée au moins une fois au cours d’un test.

Comment exploiter un tel outil ?

MangaOlivier

Olivier, qui est venu épauler Vincent, évalue avec lui ces outils et l’information qu’ils fournissent. L’indication synthétique est un taux de couverture de notre code par des tests : 65 %. Est-ce bien ou pas ?

Brute, cette information n’a aucune utilité ou presque. Son intérêt est plus de voir comment ces 65 % se répartissent sur notre code. En descendant à un niveau de détail plus fin, on découvre dans le rapport qu’une majorité de nos packages sont couverts à environ 70 % et que deux mauvais élèves se contentent de 30 %. Nous tenons nos coupables : deux packages pas assez testés, ou mal testés, ou peut-être même du code inutile !

·     Le premier, remoting, est celui de nos interfaces de communication avec d’autres systèmes. Pas le plus facile à tester puisqu’il faut quelqu’un (un simulateur) en face pour répondre et valider le fonctionnement du logiciel.

·     Le second, beans, correspond à des classes de données sans valeur ajoutée : juste des beans ayant des accesseurs get/set, mais cela fait déjà pas mal de lignes de code, d’où le mauvais résultat de la mesure.

Sur ce constat, reposons donc la question : comment exploiter un tel outil ?

Si nous établissons comme règle d’or le taux de couverture des tests doit dépasser 75 %, que va-t-il très probablement se passer ? Vous pouvez parier que le package beans va rapidement être testé à 100 % afin d’atteindre ce taux de 75 %. Le développeur étant par nature faignant, il choisira la solution de facilité, surtout si son chef l’assomme de reproches sur le non-respect de la règle d’or !

L’outil fournissait pourtant une information capitale : remoting, couche critique de notre application, est celle qui est la moins bien testée. Il nous encourage effectivement à retrousser nos manches pour mieux instrumenter ce code, peut-être en le réarrangeant afin qu’il soit plus modulaire et plus testable, peut-être en développant des simulateurs plus faciles à intégrer dans un test unitaire.

MangaVincentM

Vincent prend cela en considération et établit notre première règle d’or :

Un taux de couverture inférieur à la moyenne doit être justifié. Pas de taux absolu et inexplicable à atteindre mais, par contre, interdiction de délaisser une partie de l’application sans bonne raison.

Il considère ensuite le reste de l’application : la couverture de code est homogène, mais est-elle suffisante ? Comment va-t-elle évoluer ? Comment doit-elle évoluer ? Si nos classes de JavaBeans gonflent suite à l’ajout de méthodes get/set, notre taux va irrémédiablement baisser mais ce ne sera pas significatif. Par contre, si l’ajout de nouvelles fonctionnalités dégrade le taux de couverture, c’est que ces nouvelles fonctionnalités ne sont pas au moins aussi bien testées que le code en place.

Cela inspire donc une seconde règle d’or, que nous pourrions qualifier de protectionniste :

Le taux de couverture ne doit pas baisser avec le temps sans justification.

MangaVincentM

Vincent arrive donc rapidement à la conclusion qu’il va devoir trouver un moyen pour contrôler l’évolution dans le temps de nos indicateurs. Être capable d’estimer la couverture de test apporte des informations utiles, mais savoir si elle est en perte de vitesse et sur quels packages est bien plus important.

Notre boîte à outils est désormais comprise et correctement configurée. Il reste à Vincent à automatiser son utilisation pour mettre ces indicateurs à la disposition de tous et permettre leur suivi dans le temps. L’assurance qualité ne fonctionne que si elle est la préoccupation de tous. Donner à quelqu’un la tâche de suivre les rapports d’analyse n’a aucun sens, il passerait rapidement pour le casse-pieds de service. Mobiliser quelques instants d’attention de toute l’équipe est peu coûteux individuellement et nettement plus efficace.

Vincent pourrait continuer ainsi son tour de table des outils d’analyse de code, mais toute cette instrumentation ne sera vraiment productive que si elle vient s’intégrer dans nos outils. Nous avons déjà confié la construction de nos binaires à Maven, pouvons-nous également lui passer la main sur notre suivi qualité ?

Les rapports Maven

Comme toujours, l’intégration de nos outils d’analyse avec notre construction de projet Maven passe par des plugins. Nous pouvons, par exemple, lancer un mvn checkstyle:check pour vérifier le respect de nos règles de codage, voire le configurer pour qu’il s’exécute durant un build normal si nous nous interdisons de ne pas suivre strictement ces règles. Évidemment, c’est encore plus efficace si un tel outil d’analyse peut être intégré dans l’IDE et fournir au développeur une alerte dès que la ligne de code est saisie !

Maven propose cependant une autre forme d’intégration pour les outils qui visent à compléter la documentation sur le projet : les rapports.

Notre projet est accompagné d’une large documentation, expliquant son utilisation, ses règles de développement et l’explication de nos choix techniques. Reste à la diffuser efficacement auprès de nos utilisateurs et contributeurs.

Dans un premier temps, nous l’avons placée à côté de notre projet dans le gestionnaire de sources. Lors d’une livraison, nous accompagnons ainsi l’exécutable de l’application de sa documentation à jour. Cette approche tout-en-un est pratique pour l’utilisateur qui a téléchargé notre logiciel, mais pas pour celui qui vient juste de le découvrir et voudrait en savoir plus avant de poursuivre. Un site web serait alors une meilleure solution. Comment concilier ces deux formes de documentation ?

Par ailleurs, nous sommes fiers de notre système qualité ; aussi voudrions-nous l’exposer plus à nos utilisateurs pour démontrer notre savoir-faire et gagner leur confiance. Enfin, notre code étant soumis à une licence libre, nous voulons qu’il soit aussi facilement consultable que possible pour permettre à chacun de proposer des enrichissements.

MangaLukas

Après avoir testé diverses solutions documentaires, Lukas cherche toujours un moyen pour synthétiser les diverses sources d’information du projet. D’une part, notre wiki, dont la syntaxe simple permet de construire rapidement une documentation par enrichissement successif. D’autre part, nos outils d’analyse qualité, dont les rapports sont instructifs sur nos méthodes de travail. Ensuite, des indications techniques sur notre projet : licence, prérequis, dépendances. Enfin, une série de liens sur les aspects communautaires de notre projet : équipe de développement, liste de diffusion, système de suivi des anomalies, etc. Agréger toutes ces informations sous un point d’entrée unique, toujours à jour et homogène, voilà une tâche ambitieuse qui n’effraie pas Lukas.

Il découvre rapidement que Maven, lui-même confronté à ce problème de documentation, offre une solution complète et très riche : la génération d’une documentation complète du projet. En parallèle du cycle de vie de construction du projet, Maven propose un cycle de vie documentaire déclenché par la commande mvn site. Cette commande n’exécute qu’un seul plugin, site, mais celui-ci est l’arbre qui cache la forêt : son rôle est d’exécuter des rapports et d’en agréger le contenu dans un document unifié sous forme de site web.

Maven3

Autant Maven 3 est compatible à 99,99% avec Maven 2 sur de nombreux points, autant il y a un domaine qui a été revu de fond en comble, c’est la gestion du site ! Dans Maven 2, Nos rapports sont eux-mêmes déclarés dans notre POM, sous un élément dédié <reporting>. Ils ressemblent à s’y méprendre à des déclarations de plugins et sont d’ailleurs le plus souvent couplés avec un plugin Maven classique. Ils n’ont cependant pas exactement le même fonctionnement et vont produire un résultat (souvent un rapport brut en XML) que le plugin site va mettre en forme au sein du site du projet.

Par contre, un plugin de reporting ne tient pas compte des informations déclarées dans le <pluginManagement>, balise qui permet de regrouper la configuration de tous les plugins utilisés sur un projet. Il est donc préférable d’utiliser une propriété pour ne pas dupliquer l’information de version et risquer de tomber dans des bogues étranges. Cette dernière sera utilisée dans la déclaration du plugin dans la partie <pluginManagement> et dans la partie <reporting>.

Par ailleurs, un plugin de reporting qui serait aussi utilisé soit en ligne de commande, soit dans le cycle de vie du build, hérite toujours de la configuration définie dans la partie <reports>. Aussi, dans ce cas, et uniquement dans celui-là, il est préférable de déclarer sa configuration globale dans la partie <reporting> plutôt que d’utiliser le <pluginManagement>.

Bref, deux poids, deux mesures. Sans compter que, techniquement, cette gestion des plugins de rapports est une véritable verrue dans le code de Maven 2. Pour la nouvelle génération de Maven, tout ceci est donc passé à la trappe, et un nouveau plugin site a dû être développé. La version 3.x de ce plugin utilise donc non pas le bloc <reporting> du POM mais des rapports qu’on indique directement dans sa configuration, comme tout autre plugin Maven. Le site de Maven 3 n’est plus un cas à part, mais un plugin comme les autres.

MangaHerve

Hervé est ravi d’apprendre que Maven 3 a fait le ménage dans son code, mais devoir gérer deux versions du plugin site en fonction de la version de Maven qui construit le projet, sans parler de la déclaration des rapports, ça l’amuse modérément.

Heureusement, l’équipe de développement Maven a pensé à lui et aux nombreux utilisateurs dans son cas : le plugin site 3.x est capable de détecter l’utilisation de rapports à l’ancienne, déclarés dans le bloc <reporting>, et les interprète comme s’il était placé dans sa configuration. Il se contente d’un WARNING pour nous rappeler que ce n’est pas son mode de fonctionnement nominal, et que – si nous désirons utiliser officiellement Maven 3 – il serait préférable de nous mettre à la page.

[WARNING] The <reporting> section is deprecated, please move the reports to the <configuration> section of the new Maven Site Plugin.

Par ailleurs, depuis la version 3.0-beta-4, le plugin site gère lui même la distinction entre Maven 2 et Maven 3, il est donc capable de basculer d’une version à l’autre sans douleur. Joli tour de force ! Au final, la configuration de nos rapports s’effectue donc comme l’indique le listing 12.2, et nous permet d’associer au site web du projet la documentation javadoc et le code source du projet, navigable sous forme de pages web (« Cross Reference »).

Listing 12.2 : Configuration de nos plugins de production de raports

<build>**

    <plugins>

      <plugin>

        <groupId>org.apache.maven.plugins</groupId>

        <artifactId>maven-site-plugin</artifactId>

        <version>3.0-beta-4</version>

        <configuration>

         <reportPlugins>

            <plugin>

              <groupId>org.apache.maven.plugins</groupId>

              <artifactId>maven-jxr-plugin</artifactId>

              <version>2.2</version>

              <reports>

                <report>jxr</report>

              </reports>

            </plugin>

            <plugin>

              <groupId>org.apache.maven.plugins</groupId>

              <artifactId>maven-javadoc-plugin</artifactId>

              <version>2.7</version>

            </plugin>

          </reportPlugins>

        </configuration>

      </plugin>

    </plugins>

  </build>

 

Le plugin site se base sur un fichier dédié, src/site/site.xml, dans lequel est décrite la structure générale de notre site web. Ce fichier nous permet d’organiser le menu général du site et de pointer vers nos principales pages documentaires. Le Listing 12.3 montre celui mis en place par Lukas pour notre projet.

Listing 12.3 : Le descripteur de notre site

<?xml version="1.0" encoding="UTF-8"?>

    name="N’oublie pas la liste des courses">

  <bannerLeft>

    <name>N’oublie pas la liste des courses</name>

  </bannerLeft>

  <body>

    <links>

      <item name="Maven" href="http://maven.apache.org/"/>

    </links>

    <menu name="Guide">

      <item name="Introduction" href="user-guide/introduction.html"/>

      <item name="Setup" href="user-guide/setup.html"/>

    </menu>

    <menu ref="reports"/>

  </body>

</project>

La structure simple de ce fichier se passe de commentaires. Le seul point à souligner est la présence de la macrocommande <menu ref="reports"/> qui indique au plugin l’emplacement où insérer les liens vers nos rapports d’analyse du projet.

Les pages de notre site peuvent être écrites au choix :

·     Selon un format APT (Almost Plain Text), proche d’une syntaxe wiki et rapidement assimilé.

·     En exploitant les pages d’un wiki Confluence, ou TWiki.

·     _Via_le format documentaire DocBook (simplifié).

·     _Via_le format documentaire XDoc supporté de manière native.

·     Tout simplement à partir d’un document xHTML.

·     Ou encore, _via_un module d’extension, en exploitant tout autre format. Le bac à sable Maven comprend ainsi un module permettant d’exploiter la syntaxe XWiki.

Au premier lancement de la commande mvn site, après l’inévitable téléchargement de nombreux plugins et bibliothèques dans diverses versions, nous obtenons effectivement sous target/site la structure d’un site web pour notre projet.

La génération de ce site est déléguée par le plugin site à un sous-composant spécialisé, Doxia[42]. Cet outil prend en charge toutes les conversions nécessaires entre les formats de documents supportés et le document à construire.

Autre chose que du HTML

Doxia est donc le moteur qui va formater notre documentation. Utilisé par le plugin site, il produit des pages HTML. Utilisé par le plugin pdf, il produit un fichier PDF regroupant toute la documentation du projet. La commande mvn pdf:pdf permet ainsi de produire une documentation format papier, toujours à jour en fonction des diverses sources que nous avons agrégées.

Comme le plugin site et son fichier site.xml, le plugin pdf s’appuie sur un descripteur pdf.xml qui lui indique comment assembler les éléments documentaires pour produire le résultat. De la même façon, et avec les moteurs de rendu adéquats, Doxia pourrait produire notre documentation dans tout un ensemble de formats qu’il reste à imaginer (voir Figure 12-01).

Figure 12-01

Génération de la documentation en différents formats grâce à Doxia.

Exploiter notre gestion documentaire

Nous sommes donc désormais en mesure d’analyser le code de notre projet avec l’aide d’une large panoplie d’outils et d’agréger le résultat dans une documentation complétée par ce que nous aurons pris le temps de rédiger dans des formats variés, le tout en une seule commande comme Maven nous y a habitués.

Nous sommes tous attentifs à ces rapports d’analyse de code que nous pouvons désormais construire sur notre poste de développement, à moins de consulter le site généré toutes les nuits sur notre serveur d’intégration continue – il serait dommage qu’il reste inutilisé pendant cette période où nous, pauvres humains, devons nous reposer. Nous pouvons identifier les éléments de code qui violent des règles et corriger consciencieusement ces défauts, espérant ainsi que les chiffres du lendemain seront meilleurs.

68 %, qui dit mieux ?

Rapidement, un besoin nouveau s’exprime : lorsque nous constatons qu’un élément du projet est sous-documenté, nous ajoutons quelques fichiers APT pour combler le manque. La perception de ce défaut de documentation est totalement subjective mais nous arrivons rapidement à un consensus sur le niveau obtenu. Par contre, le rapport indiquant le taux de couverture de nos tests est plus délicat à interpréter. 68 %, est-ce bien ? Est-il utile de vouloir pousser ce taux au-delà, ce qui pourrait rapidement nous amener à écrire des tests sans intérêt juste pour approcher des 100 %. Pire, nous pourrions être tentés d’écrire de nombreux tests faciles pour obtenir un bon chiffre en délaissant des parties de code moins évidentes à tester.

68 %, ça ne veut rien dire. Ce qui est intéressant, c’est de voir que le mois dernier, nous étions pour le même package à 82 % ! Il semble que nous avons laissé cette partie du projet se dégrader ! À moins que nous n’ayons une bonne explication pour cette baisse, une action doit être entreprise pour corriger le tir.

Les indicateurs qualité sont rarement très pertinents tels quels, et, en tout cas, la valeur cible à respecter dépend du contexte du projet, de ses objectifs et souvent de l’élément technique considéré. Notre code d’accès à la base devrait être proche de 100 % de couverture de test, sinon cela voudrait dire que certaines requêtes ne font pas l’objet de tests et qu’une modification dans notre modèle ne serait pas détectée. De même, tous les aspects fonctionnels (le code métier utile) doivent être largement couverts. En revanche, d’autres parties de notre code, présentant de nombreux cas d’erreurs qui ne donnent pas lieu à un traitement précis autre que "erreur interne, merci de réessayer plus tard", peuvent légitimement obtenir une couverture moindre.

L’entropie augmente

Il n’existe pas de juste milieu absolu. Néanmoins, on constate l’application universelle du second principe de la thermodynamique : le code tend toujours à se dégrader pour devenir moins organisé et moins bien testé. Des tests obsolètes sont supprimés, le nouveau code écrit dans la chaleur d’un coup de bourre est peu ou pas instrumenté… Juste maintenir le code au même niveau demande une débauche d’énergie, de temps et donc de budget !

Pour détecter rapidement une telle dérive, rien ne vaut un bon graphe synthétique historisant l’évolution du projet. De manière assez amusante, on peut souvent deviner les dates de livraison sur de telles courbes : on constate un infléchissement de la courbe dans la semaine qui précède la livraison et (dans le meilleur des cas) une reprise lente dans les semaines qui suivent.

Maîtrise de _S_[43]

MangaVincentM

Le spécialiste en thermodynamique de l’équipe c’est Vincent, et c’est donc lui qui nous propose spontanément un outil pour être en mesure de mesurer l’entropie de notre projet. Il a déjà passé de longues heures à analyser les nombreux rapports produits par Maven dans notre site et a rapidement compris que ce ne sont que des données brutes. Il faut être capable de les lire à des altitudes différentes :

·     À 30 000 pieds, on doit avoir en un coup d’œil une vision globale du projet, très imparfaite mais parlante. Le projet est-il dans le rouge ou non ? Quel est le type de violation le plus couramment constaté et sur lequel il faudra faire un effort de communication et de formation ?

·     À 3 000 pieds, on doit être en mesure d’identifier les modules et de distinguer celui qui joue le mouton noir (espérons qu’il n’y en ait qu’un seul), la règle de codage la moins bien respectée.

·     À 300 pieds, on peut pointer du doigt les packages dans lesquels il serait bon de passer un peu plus de temps, ou la règle de codage dont les développeurs ont sans doute mal compris la portée.

·     À 30 pieds, on accède au Top 10 des classes à problème, et on commence à regarder les noms des auteurs des dernières modifications pour savoir avec qui il faudra discuter de manière aimable et constructive lors de la prochaine pause-café.

·     À 1 mètre, on déroule le code source ligne par ligne et on y identifie chaque violation. En binôme avec le développeur qui a eu la maladresse d’écrire ce code, on peut discuter du bien-fondé de la règle et des façons d’écrire un code plus propre et plus conforme à nos exigences.

Ce Google Earth pour code existe, il s’appelle Sonar.

Sonar

Sonar[44] est une application web qui va stocker dans une base de données tous les indicateurs et statistiques extraits par nos rapports d’analyse de code. En outil convivial et soucieux de sa simplicité d’utilisation, il est proposé avec un serveur d’application et une base de données embarqués, ce qui limite la procédure d’installation au strict minimum. Pour une utilisation en entreprise de manière plus stratégique, on pourra cependant le déployer sur un serveur et le configurer pour utiliser une base de données dédiée.

Les données de Sonar sont accessibles via un frontal web synthétique, qui donne les grandes tendances du projet. C’est notre vue à 30 000 pieds du projet (voir Figure 12-02).

Figure 12-02

Synthèse de nos indicateurs qualité dans Sonar.

La représentation du projet en blocs colorés est particulièrement compacte et pertinente. Pour un critère donné – ici, le respect des règles de codage –, un bloc de grande surface correspond à un grand volume de code et la couleur au niveau de satisfaction du critère. Un petit bloc rouge dans un ensemble vert pourra donc être acceptable si on sait le justifier, alors qu’un grand bloc orange sera de très mauvais augure. Chaque élément de cette synthèse est un lien vers plus de détails. On va ainsi descendre de lien en lien jusqu’aux classes du projet puis ouvrir son code source pour constater la ligne de code qui a été identifiée par l’analyse de code (voir Figure 12-03).

Figure 12-03

Détail des violations constatées par Sonar dans notre code source.

Sonar va extraire de notre projet Maven l’ensemble des indicateurs qu’il prend en charge via un plugin dédié. Celui-ci va directement enrichir la base de données du serveur Sonar pour la construction en cours. Le serveur exploitera ensuite les données pour fournir une synthèse ainsi qu’un historique. Le Listing 12.4 montre la configuration de ce plugin dans notre POM. Le plugin sonar utilisant de nombreuses propriétés, il est plus simple de les configurer comme telles et d’invoquer la tâche mvn sonar:sonar.

Listing 12.4 : Configuration du plugin Sonar

 <profile>

      <id>sonar</id>

      <properties>

        <sonar.host.url>http://sonar.geegol.com</sonar.host.url>;

        <sonar.jdbc.url>jdbc:mysql://mysql.geegol.com:3306/SONAR?autoReconnect=true</sonar.jdbc.url>

        <sonar.jdbc.driver>com.mysql.jdbc.Driver</sonar.jdbc.driver>

        <sonar.jdbc.username>sonar</sonar.jdbc.username>

        <sonar.jdbc.password>sonar</sonar.jdbc.password>

      </properties>

    </profile>

Pour produire ces métriques de notre projet à intervalles réguliers, nous décidons de laisser notre serveur d’intégration continue effectuer une construction dédiée toutes les nuits – il faut bien rentabiliser la machine. Sur notre serveur Hudson, nous avons la bonne surprise de découvrir un plugin dédié à Sonar, qui nous économise la configuration de cet outil dans notre POM. Il suffit de fournir quelques paramètres dans la console d’administration de Hudson et de configurer une construction du projet à heure fixe.

Nous constatons que la complexité mesurée de notre code grimpe régulièrement (voir Figure 12-04). C’est une dérive typique qui prend pied de manière maligne, répartie un peu partout dans le code et sans que personne s’en sente responsable. Il est temps de sensibiliser l’équipe, par exemple en lui montrant cette simple courbe, sur l’influence que peut avoir un petit effort quotidien de clarification et de simplification du code.

Figure 12-04

Évolution de nos indicateurs qualité.

La Figure 12-05 indique également le Top 10 des violations constatées, ce qui nous dira immédiatement sur quoi nous devons mettre l’accent. Notre session mensuelle de débriefing est déjà toute tracée !

Sonar n’est définitivement pas un outil de flicage, c’est un assistant extrêmement puissant pour accompagner le travail d’une équipe et pointer du doigt ses dérives. Le développeur parfait n’existe pas, mais le développeur bien outillé peut tenter de s’améliorer.

Figure 12-05

Classement des violations les plus souvent identifiées

Conclusion

Accompagner notre projet d’un bon support documentaire et d’un bon suivi qualité est une tâche ambitieuse, qui peut s’appuyer sur de très nombreux outils. Inutile de vouloir se suréquiper si on n’en a pas compris l’utilisation. Maven aide à mettre en place les outils progressivement, à apprendre à les exploiter. Notre ingénieur qualité devrait en toute logique nous aider à accomplir cette initiation et, une fois mûrs, nous pourrons en tirer tout le bénéfice.

Maven n’est ici que le catalyseur qui nous aide à utiliser des outils existants. Cependant, la facilité avec laquelle on introduit un outil d’analyse dans un projet Maven encourage à l’essayer, à en découvrir l’usage, et progressivement à mettre en place une culture du coder proprement (livre de Robert C. Martin que je vous recommande chaudement, chez le même éditeur).