Nous avons vu dans le post précédent ‘Cas d’utilisation – Ensemble et sans heurts‘ quels use cases sont les plus souvent appliqués avec un outil d’analyse de code, et permettent d’en tirer le plus grand bénéfice:
- Quality Gate afin de valider la livraison d’une nouvelle version applicative.
- Gestion de SLAs et benchmarking des fournisseurs.
- Processus d’Intégration / Amélioration continue des équipes de développement.
Il est recommandé de combiner ces trois use cases pour une meilleure synergie et afin d’en optimiser les résultats. Néanmoins, leur mise en œuvre est différente selon que vous êtes dans un contexte de :
- Développement interne : Intégration / Amélioration continue + Quality Gate.
- Développement externalisé : Quality Gate + SLAs.
Quelles sont métriques les plus importantes pour ces use cases ?
En fait, l’objectif en matière d’Amélioration Continue et de SLAs doit rester simple et réaliste.
Réaliste signifie concrètement : atteignable. Si vous demandez à vos équipes de développement un résultat parfait sur 50 best practices, ce n’est pas réaliste. Personne ne peut avoir 50 mesures différentes en tête, 50 bonnes pratiques de programmation à respecter absolument. Même s’ils les connaissent, même s’ils savent qu’ils doivent éviter de créer des violations de ces règles de qualité, il est impossible de toutes se les rappeler et vous ne pourrez pas éviter la faute d’attention occasionnelle. Et si l’objectif n’est pas atteignable, l’équipe se décourage rapidement et cesse de prêter attention et le processus mis en œuvre sera un échec.
Fixez un objectif atteignable avec un minimum de 10 à 12 régles, 15 grand maximum.
Simple signifie concrètement : objectivement mesurable. Par exemple, vous décidez de fixer comme but d’atteindre 99.99% de qualité. Mais 99.99% de quoi ? Du nombre de lignes de code ? Du nombre d’objets auxquels s’applique la bonne pratique ? Imaginons une règle (classique) en matière de gestion des exceptions selon laquelle un ‘throw’ Java ne doit pas être vide. Elle ne s’applique évidemment qu’aux méthodes qui implémentent une logique métier. Si une classe a 100 setters/getters sans aucune logique métier, la règle s’applique-t-elle ? Si cette classe comporte 200 lignes de code ou plus, allez-vous inclure ces lignes dans votre calcul ? Non seulement cela devient compliqué, mais de surcroît vous allez pénaliser le développeur qui aura une classe métier avec 20 méthodes implémentant un ‘throw’ : il suffit d’un oubli pour atteindre 5% d’erreur, ce qui pénalise énormément ses résultats.
L’objectif le plus simple et le plus facilement mesurable est : 0 défaut. Aucune malpractice n’est tolérée, quelques soient le nombre de lignes, de méthodes, de classes, etc.
Donc 10 ou 12 métriques avec une tolérance 0.
Et quelles sont les règles les plus importantes pour lesquelles nous n’accepterons aucun défaut ? Celles qui constituent une erreur critique en termes de développement, parce que l’impact sur le comportement de l’application et pour l’utilisateur final sera critique. Une mauvaise gestion des erreurs peut aboutir à une page blanche pour l’utilisateur ou une page d’erreur par défaut incompréhensible, l’interruption du traitement, une transaction non finalisée, voire même une corruption de données.
Il en va de même pour l’utilisation de certaines classes génériques qui ne permettent pas de spécialiser une exception et de comprendre et tracer l’erreur survenue. Egalement, certaines syntaxes qui peuvent s’avérer dangereuses en matière de corruption de données et de sécurité.
Cobol et ABAP ne connaissent pas la notion de classes ou de méthodes mais les principes restent les mêmes : toujours utiliser un code retour lorsque l’on appelle une fonction ou un traitement de base de données, éviter les instructions qui interrompent les traitements tels que Break ou Stop Run. Ces technologies sont également très sensibles à la performance donc on ajoutera tous les traitements coûteux en temps de réponse dans le code SQL et/ou dans des boucles.
On favorisera donc des métriques telles que :
- Java : Empty Try block, Empty Finally block, Empty If statement, Empty While Statement, Illegal throws (java.lang.error, java.lang.RuntimeException), Equals HashCode, Array stored directly, …
- Cobol, Abap : If without Endif, Others in Case, When Other in Evaluate, Break, Stop Run, Sort, Select *, Select Distinct, Group by, Select in Select, Cursor inside a loop, Open/Close in a loop, …
Ces règles présentent l’avantage d’être également acceptables au sein d’un SLA pour un provider et un objectif de 0 défaut est facilement mesurable.
Qu’en est-il maintenant des règles d’acceptation ou de rejet d’une version d’application dans la Quality Gate ? Tout d’abord on incluera logiquement les métriques précédentes : si la régle de 0 défaut s’applique au niveau des développeurs, on ne veut pas retrouver ces défauts dans l’application, que l’équipe soit interne ou externe.
On incluera également quelques mesures en matière de maintenabilité, c’est-à-dire des métriques qui mesurent la qualité du code en matière de coûts de maintenance et non pas de risques pour l’utilisateur.
Imaginons une application J2EE avec 500 classes comportant en moyenne 20 méthodes, soit 1 000 méthodes en tout. On admet qu’un code Java de qualité puisse compter 7.5% d’objets complexes et 2.5% d’objets très complexes, donc 750 méthodes complexes et 250 méthodes très complexes dans notre exemple. Ce code est le plus coûteux à faire évoluer parce qu’il est difficile à comprendre, et aussi le plus dangereux puisque le risque d’introduire un défaut en cas de modification est le plus élevé.
Imaginons maintenant que l’équipe de projet ajoute 5% de méthodes complexes et très complexes à chaque version. Ce chiffre est assez limité, cela ne représente qu’une douzaine de méthodes très complexes pour les 250 existantes. A raison de 4 versions par an, le total des règles les plus complexes aura augmenté de plus de 20% et la complexité de l’application aura doublé en moins de 4 ans. Sachant l’impact de cette complexité sur vos budgets, vos plannings et le nombre de bugs pour les utilisateurs, l’on comprend rapidement pourquoi il est souhaitable de surveiller toute dérive dans ce domaine.
On pourra donc rajouter ce type de métriques au niveau d’un SLA et donc d’une Quality Gate, et d’autres mesures qui impactent la maintenabilité telles que le % de code dupliqué, % de code en commentaires (Commented-out LOC), … et évidemment, si l’outil sait le calculer, la Technical Debt (il faudra prendre en compte l’augmentation de la taille du code pour cette mesure). Le pourcentage de commentaires peut également constituer une métrique intéressante lorsque le code est outsourcé.
Evidemment, il est conseillé de vérifier ces métriques le plus tôt possible, ce qui suppose de les faire appliquer au sein d’un processus d’Intégration continue. Cependant, je ne recommande pas de politique ‘0 défaut’ à ce niveau : l’important est d’arriver à la Quality Gate sans aucun objet nouveau complexe, pas de les supprimer systématiquement de tout ‘build’. Une certaine marge de manœuvre, pour ne pas dire d’autonomie, peut-être laissée à l’équipe de projet dans ce domaine. On veillera néanmoins à les sensibiliser sur ces règles, dont la bonne application leur profite d’ailleurs.
A noter que les erreurs qui représentent un risque pour l’utilisateur peuvent également impacter fortement les coûts de maintenance de l’application. Une mauvaise gestion des erreurs signifie un temps de détection du bug et donc de correction assez élevé.
Cette liste de métriques n’est pas absolue et nous ne prétendons pas lister celles-ci comme les 10 à 20 métriques les plus importantes, mais à titre d’exemple pour ces trois use cases. Vous pouvez constituer votre propre liste selon vos propres critères: les technologies utilisées pour vos applications, le niveau de maturité de vos équipes, l’alignement métier / IT (voir sur ce sujet ‘Quelle est la première question ?‘), si les applications sont maintenues en interne ou ‘outsourcées’, etc.
Les 10 à 20 métriques les plus importantes sont celles qui vous permettront d’améliorer la qualité de vos applications en tirant le maximum de bénéfices de ces trois cas d’usages.
Cette publication est également disponible en Leer este articulo en castellano : liste des langues séparées par une virgule, Read that post in english : dernière langue.