Couverture de code C++ avec CMake et GCOVR

Bensuperpc août 07, 2025 [Software] #Features #Code coverage #Testing #GCOVR

Couverture de code en C/C++, avec CMake et GCOVR

Introduction

Ce tutoriel montre comment configurer un projet C/C++ avec CMake et GCOVR afin de générer des rapports de couverture de code, cela permet de vérifier précisément quelles parties du code source et quelles branches conditionnelles (if, switch...) sont effectivement couvertes par les tests.

Nous utiliserons un petit projet d'exemple basé sur Google Test, mais la méthode est également compatible avec d'autres frameworks comme Catch2, Boost.Test ou Doctest.

Exigences minimales

Une distribution comme Ubuntu 22.04, un Debian 12 ou supérieur est recommandé dans le cadre de ce tutoriel, mais vous pouvez utiliser n'importe quelle distribution Linux avec les versions requises des outils.

Installation des dépendances

Pour installer les dépendances nécessaires, vous pouvez utiliser les commandes suivantes :

Pour Ubuntu/Debian :

sudo apt-get install cmake build-essential g++ gcovr ninja-build libgtest-dev

Pour Fedora :

sudo dnf install cmake gcc-c++ gcovr ninja-build gtest-devel

Pour Arch Linux :

sudo pacman -S cmake gcc gcovr ninja gtest

Qu'est-ce que GCOVR ?

GCOVR est un outil open source qui permet de générer des rapports de couverture de code C/C++ à partir des données générées lors de l'exécution des tests.

Projet d'exemple

Le projet d'exemple est une simple application et deux bibliothèques C++, une pour les mathématiques et une pour la physique.

Voici l’arborescence du projet :

.
├── CMakeLists.txt
├── main.cpp
├── math
   ├── CMakeLists.txt
   ├── math.cpp
   └── math.hpp
├── physics
   ├── CMakeLists.txt
   ├── physics.cpp
   └── physics.hpp
└── tests
    ├── CMakeLists.txt
    └── test.cpp

4 directories, 10 files

Vous pouvez télécharger le projet d'exemple: tuto_coverage.7z

Compilation avec couverture

Pour que la couverture de code fonctionne, le projet doit être compilé avec les options : -O0 -g --coverage et --coverage pour le linkage.

cmake -S . -B build -G Ninja -DCMAKE_CXX_FLAGS="-O0 -g --coverage" -DCMAKE_EXE_LINKER_FLAGS="--coverage" && cmake --build build

L'option --coverage est équivalente à -fprofile-arcs -ftest-coverage pour GCC/Clang, dans un projet classique, il est préférable d'utiliser des presets CMake plutôt que de spécifier les options manuellement.

Exécution des tests

Une fois le projet compilé, vous pouvez exécuter les tests, cela générera des fichiers sur lesquels GCOVR s’appuie pour générer les rapports de couverture:

ctest --test-dir build --output-on-failure --no-tests=error --repeat until-fail:1 --schedule-random --parallel 1
OptionDescription
--test-dir buildSpécifie le Répertoire contenant les tests
--output-on-failureAffiche la sortie des tests échoués
--no-tests=errorGénère une erreur si aucun test n'est trouvé
--repeat until-fail:1Répète les tests jusqu'à ce qu'un échec se produise, ici 1 fois
--schedule-randomFait exécuter les tests dans un ordre aléatoire
--parallel 1Exécute les tests en parallèle, ici 1 test à la fois

Vous obtiendrez une sortie similaire à :

Test project /home/bensuperpc/tuto_coverage/build
    Start 3: MathTests.Mul
1/7 Test #3: MathTests.Mul .....................   Passed    0.00 sec
    Start 7: PhysicsTests.GravitationalForce
2/7 Test #7: PhysicsTests.GravitationalForce ...   Passed    0.00 sec
    Start 5: PhysicsTests.Speed
3/7 Test #5: PhysicsTests.Speed ................   Passed    0.00 sec
    Start 2: MathTests.Sub
4/7 Test #2: MathTests.Sub .....................   Passed    0.00 sec
    Start 1: MathTests.Add
5/7 Test #1: MathTests.Add .....................   Passed    0.00 sec
    Start 6: PhysicsTests.KineticEnergy
6/7 Test #6: PhysicsTests.KineticEnergy ........   Passed    0.00 sec
    Start 4: MathTests.Div
7/7 Test #4: MathTests.Div .....................   Passed    0.00 sec

100% tests passed, 0 tests failed out of 7

Total Test time (real) =   0.02 sec

Rapport HTML avec GCOVR

Après l'exécution des tests, vous pouvez générer un rapport de couverture avec GCOVR, ici nous générons un rapport HTML pour visualiser la couverture de code, mais vous pouvez également générer des rapports en texte brut, XML ou JSON.

gcovr --root "." --decisions --calls --html-theme "green" --exclude "tests/*" --exclude "build/*" --exclude "main.cpp" --html --html-details --output "build/coverage.html"
OptionDescription
--root "."Définit le répertoire racine pour la couverture
--decisionsInclut les décisions de couverture dans le rapport
--callsInclut les appels de fonction dans le rapport
--html-theme "green"Définit le thème du rapport HTML en vert
--exclude "tests/*"Exclut les fichiers de test du rapport
--exclude "build/*"Exclut les fichiers de build du rapport
--exclude "main.cpp"Exclut le fichier main.cpp du rapport
--htmlGénère un rapport HTML
--html-detailsInclut les détails dans le rapport HTML
--output "build/coverage.html"Spécifie le nom du fichier de sortie pour le rapport HTML

Une fois le rapport HTML généré, vous pouvez l'ouvrir dans votre navigateur pour visualiser la couverture de code, il devrait être généré dans le fichier build/coverage.html.

Voici le rendu du rapport sur le navigateur :

Page principale
Page principale
Page secondaire
Page secondaire

Rapport en XML ou JSON

Vous pouvez également générer un rapport en XML ou JSON pour une intégration avec d'autres outils :

gcovr --root "." --decisions --calls --exclude "tests/*" --exclude "build/*" --exclude "main.cpp" --xml-pretty --output "build/coverage.xml"

Ou en JSON :

gcovr --root "." --decisions --calls --exclude "tests/*" --exclude "build/*" --exclude "main.cpp" --json-pretty --output "build/coverage.json"

Sources