Après avoir défini précisément ce que recouvrait la notion de « qualité logicielle », ce second article aborde concrètement la question des mesures de la qualité.
Sans mesure quantifiée de la qualité, celle ci ne pourra pas être gérée et comme le dit le gourou du management Peter Drucker :
Whats gets measured gets managed. Peter Drucker.
Malheureusement, le revers de la médaille est qu’à partir du moment où une métrique est définie, les développeurs optimiseront « cette » métrique… au détriment des autres métriques qui seront suivies avec moins d’attention voire pas du tout. Il est donc important de définir clairement les métriques qualité suivies.
Définir les exigences de qualité par des métriques simples, peu nombreuses et pertinentes
Première étape : définir les exigences de qualité avec des métriques qui doivent être simples, peu nombreuses et pertinentes afin que nous soyons confiants dans leurs suivies et leurs impacts. Elles peuvent être abordées par exemple pendant la rétrospective à l’issue de chaque sprint.
Je propose cinq métriques que j’estime fondamentales pour la qualité et qui permettent de réaliser le « radiateur qualité » d’un projet.
- Complexité : la mesure de la complexité agrégée en une seule valeur par ajout des intrications (dépendances cycliques) entre modules et de la complexité cyclomatique est une excellente mesure. Cette mesure est faite par exemple par l’outil Structure 101. Le respect des règles de dépendances entre modules (technique mais surtout métier) est un must-have et le coeur de Structure 101.
- Respect des règles de codage : les règles de codages fournissent un bon indicateur de la qualité du code source. Ces règles de vérification statiques sont détaillées pour chaque outil : PMD pour les mauvaises pratiques, Findbugs pour les bugs potentiels et Checkstyle pour les conventions de codage. Sonar agrège ces 3 outils.
- Test coverage : le test coverage permet de s’assurer qu’une majorité du code source est testée avec des outils comme Clover, Cobertura ou Emma. Les revues de code permettent de s’assurer de la pertinence des tests (des techniques avancées, comme le mutation testing avec Javalanche, existent également). Bien sûr, tous les tests doivent s’exécuter avec succès. La traçabilité des tests vers le besoin (sous forme de Use Case ou de User Story) est importante.
- Stabilité : elle peut être suivie par la mesure du nombre de bug éventuellement par catégorie (bloquant, majeur, mineur). Cela permet de déterminer les fonctionnalités les plus instables et de décider des actions correctives à entreprendre. Cette mesure peut être faite par unité de temps (nombre de bug par mois) mais également par quantité de ligne de code et par nombre de jour homme dépensé. Sans prétendre à être une mesure absolue, c’est une mesure relative qui permet d’évaluer les différences entre les projets d’une même entreprise. Cette même mesure peut d’ailleurs être faite entre différents modules d’une même application.
- Résultats des revues de conception et de code : pour chaque module, la note de synthèse de la dernière revue est donnée.
Le schéma ci-dessous illustre un tel « radiateur qualité » :
Effectuer les mesures et produire le rapport « qualité »
Seconde étape : effectuer les mesures et produire le rapport, à l’issue de chaque sprint par exemple. Ces mesures se font bien sûr de manière régulière afin de pouvoir suivre les évolutions dans le temps. Le point important est de définir le seuil au delà duquel la correction est jugée obligatoire et ce afin de ne pas augmenter la dette technique. Différents seuils permettent d’avoir un synoptique de la qualité : vert, jaune, orange, rouge. La définition de chacun des seuils est à l’appréciation de chaque équipe.
D’autres mesures à effectuer plus ponctuellement
L’efficacité, plus couramment dénommée performance, est un attribut important mais qui sera évalué de plusieurs manières :
- par du profiling, notamment lors des revues de code et sur du code dont on sait pertinement qu’il aura une influence importante sur la perception de l’efficacité du logiciel.
- par l’analyse des logs d’exécution, notamment ceux liés à la persistance (logs des requêtes SQL), car l’interaction base de données reste la source principale des problèmes de performances d’une application de gestion
- par des tests de charge qui demandent cependant un investissement important. Ils sont typiquement menés en milieu et fin de projet afin de respectivement corriger et valider les performances de l’application.
Complexité sémantique
Une mesure que je trouve très importante mais encore immature est la complexité sémantique du logiciel. Afin d’évaluer la charge cognitive nécessaire à la compréhension d’un code, la complexité est une première mesure très utile. Néanmoins, une mesure complémentaire concerne la qualité du nommage (le signifiant) permettant de déduire si celui ci est facilement compréhensible et surtout s’il est fortement relié au vocabulaire du domaine (et donc au signifié). Un outil produit donc le nuage de mots utilisés au sein du code source (nom de classe, de méthodes, de variable) et permet de vérifier son adéquation avec le modèle du domaine. Un tel outil existe même s’il demande à mûrir (paramétrage, utilisation standalone ou en intégration continue, etc.).
Conclusion
La qualité doit être mesurée afin d’être gérée et il est important de concentrer l’attention de l’équipe et des managers sur des métriques agrégées et pertinentes, cet article propose une manière concrète de mettre en place une activité de mesure de la qualité.
Je me permets de vous poser la question : quelle différence entre métrique et mesure ? Parce que les 2 sont utilisés pour indiquer la même chose, et alors pourquoi ne pas appeler les métriques des mesures dans ce cas ?