Qualité de code : Mesurer la couverture du code

Analyse de code à la loupe

Cet article a pour objectif d’expliciter la notion de couverture de code et de montrer comment tout un chacun peut mettre en œuvre des métriques inclues dans gitlab sur son projet à Systerel.

Qu’est-ce que c’est ?

Couverture de code

En génie logiciel, la couverture de code est une mesure utilisée pour décrire le taux de code source exécuté d’un programme quand une suite de test est lancée. Ces informations permettent de vérifier quelle brique de code est parcourue, et donc testée.

Deux informations sont généralement retournées :

  • Le taux de couverture (en %)

  • Un rapport donnant la couverture effective par fichier

Comment ça marche ?

Le Gitlab Systerel intègre déjà ce genre de mesure. Pour les utiliser, il est nécessaire d’avoir des connaissances en intégration continue gitlab. Les informations adéquates peuvent se trouver sur le blog.

Bien sûr, la mesure de la couverture ne concerne que les étapes de test de l’intégration continue.

Exemple

Projet interne — Composant SNMP Nomad Digital

La couverture a été mise en place sur le projet C943 à la demande du client Nomad Digital. La demande initiale était de donner à Nomad des KPIs de mesures de code utilisés par Systerel. À ce jour, il n’y a pas de KPI “générique” sur le sujet à Systerel. Une rapide étude a été faite pour utiliser ce qui était déjà inclus dans Gitlab et le mettre en exécution.

En version gratuite, les informations sont accessibles dans les merges request. Pour la couverture de code, Gitlab utilise des rapports au format Cobertura.

Affichage de la MR donnant le taux de couverture du code pour le projet C943

Affichage du taux de couverture dans une MR du projet C943, composant SNMP.

Affichage du diff de la MR donnant la couverture par ligne du code pour le projet C943

Affichage de la couverture par ligne dans le diff d’une MR du projet C943, composant SNMP

Dans l’image précédente, la couverture s’affiche via le liseré à gauche :

  • Vert : ligne couverte

  • Rouge : ligne non couverte

Mise en place

La documentation est disponible en ligne sur le site de gitlab:

Dans la suite, nous allons vous montrer comment mettre en place ces mesures sur votre projet. Dans notre exemple, on se base sur du code Python, mais le principe reste le même pour les autres langages supportés (Java, …)

Instanciation du projet gitlab

Créer un projet gitlab est décrit ici : ici.

Dans notre cas, nous allons appeler notre repo test_code_coverage.

Nous allons l’instancier avec les fichiers suivants :

  • main.py : script comptant le nombre de paramètres passés, et le comparant au chiffre 2.

import sys

# total arguments
n = len(sys.argv)
print("Total arguments passed:", n)

if n < 2:
   print ("Less than 2")
elif n == 2:
   print ("Equal to 2")
else:
   print ("Not less than 2")
  • .gitlab-ci.yml

image: python:latest

run:
  script:
   - python main.py

Astuce 1

Il est possible de créer / supprimer / éditer des fichiers directement sur Gitlab (pratique dans le cas de légère modification sans workflow défini).

Astuce 2

Gitlab reconnaît automatiquement le fichier “.gitlab-ci.yml” et propose un pipeline editor : le fichier yaml est analysé en temps réel et les erreurs sont signalées.

Après le push de ces 2 fichiers sur votre repo git, le pipeline doit se déclencher et être “success”. Comme aucun paramètre n’est passé, le résultat est “Less than 2”.

Update du .gitlab-ci.yml pour ajouter de la couverture de code

La première étape et d’aller jusqu’à la création d’une merge request. Le workflow est à définir au niveau du projet, mais typiquement voici ce qui est fait :

  1. Création d’une issue

  2. À partir de l’issue, création d’une merge request avec création automatique de la branche

Maintenant que votre branche est créée, nous allons modifier le .gitlab-ci.yml pour ajouter de la couverture de code :

image: python:latest

run:
  # expression régulière qui vient parser la console du pipeline pour récupérer la couverture globale et l'afficher dans la merge request. Va de pair avec "coverage report"
  coverage: '/TOTAL.*\s([.\d]+)%/'
  script:
   #installation de la librairie "coverage.py" utiliser pour la couverture de code
   - pip install coverage
   #modification de la ligne de lancement du python pour utiliser la librairie coverage.py
   - coverage run -m main
       #affiche le rapport dans la console, utilisé pour donner le pourcentage total de couverture
   - coverage report
       #génération d'un rapport xml
   - coverage xml
       #génération d'un rapport html
   - coverage html
  artifacts:
       #archivages des rapports XML (1 fichier) et HTML (dossiser htmlcov)
   paths:
    - coverage.xml
    - htmlcov/
   #rapport au format cobertura ==> sera processé par Gitlab
       reports:
     coverage_report:
       coverage_format: cobertura
       path: coverage/cobertura-coverage.xml

Une fois le pipeline passé, le résultat est visible dans la merge request :

  • Overview” : 62% de couverture

  • Changes” : on passe uniquement dans la condition “n<2”

Example de la couverture de code

Résultat de la couverture de code dans l’exemple

Vous pouvez également consulter les rapports XML et HTML dans les artefacts du build. Dans le cas des rapports HTML, le dossier complet est à télécharger pour afficher correctement le rapport (prise en compte du fichier style.css présent).

Multiples stages avec de la couverture de code

Dans un cas pratique, il peut y avoir plusieurs jobs de tests, et donc plusieurs couvertures de code à gérer :

  • L’ajout de chaque rapport est pris en compte sur git : on peut voir dans la merge request le nombre de “hits”.

    • ==> Le nombre de fois où on passe par la ligne de code.

  • En revanche Gitlab fera une moyenne des valeurs de tous les champs “coverage” matchant avec la regexp du fichier de CI.

    • ==> Il peut être nécessaire pour avoir une vue complète de rajouter un “stage” combinant tous les rapports et donnant la mesure globale de couverture.

Badge

Il est possible d’ajouter un badge au projet donnant la couverture de code sur la branche principale. Pour ce faire :

  • Aller dans Settings / General / Badges

  • Ajouter un badge comme suit (exemple pour la branche par défaut) :

    • Name : coverage

    • Link : https://gitlab.aix.systerel.fr/%{project_path}/-/commits/%{default_branch}

    • Badge image URL : https://gitlab.aix.systerel.fr/%{project_path}/badges/%{default_branch}/coverage.svg

Badge donnant le taux de couverture du code

Affichage du taux de couverture dans une MR du projet C943, composant SNMP.

Conclusion

Gitlab propose des choses assez intéressantes sur la couverture de code. La couverture complète est malheureusement accessible uniquement par le téléchargement des artefacts adéquats. Les seules informations intégrées à l’UI sont le badge sur la page d’accueil et les informations dans les MR.

Cependant, on ne parle ici que de métriques et d’affichage. Le nerf de la guerre, c’est réussir à correctement tester son code, ce qui est un tout autre sujet ! Il est bon de rappeler que la couverture de code n’est pas une fin en soi, mais un outil permettant de détecter les trous dans la couverture de test.

Dans tous les cas, la mise en place de ces outils permet de mieux manager son code et ainsi pouvoir prévenir de potentiels bugs.

Commentaires