Prise en main avec CppUTest
Oiseau
14 mai 2017
1 min read

Points Clés
CppUTest est un framework de test de style xUnit léger et activement maintenu pour C/C++, avec une couche d'intégration C qui fonctionne parfaitement même dans les bases de code lourdes en C.
Vous pouvez l'installer via les gestionnaires de paquets (distributions Linux, Homebrew) ou cloner le dépôt GitHub.
Une configuration minimale se compose de :
un répertoire de production
src/,un répertoire de tests
t/,un exécuteur de tests (
CommandLineTestRunner), etdes modules de test utilisant les blocs
TEST_GROUPetTEST().
CppUTest fournit un assistant MakefileWorker.mk qui simplifie la compilation des tests, l'édition de liens avec les bibliothèques, et la gestion des indicateurs.
La détection des fuites de mémoire est activée par défaut grâce aux remplacements de malloc/free, capturant les fuites au sein du code source testé.
La couverture de code via gcov s'intègre facilement en activant
CPPUTEST_USE_GCOV=Y, en produisant des rapports de couverture complets et des résumés HTML.Le framework inclut des fonctionnalités avancées : moquerie, plugins, scripts d'aide, et interopérabilité directe avec C — utile pour les bases de code d'entreprise complexes.
Points forts des Q&A
Qu'est-ce que CppUTest et pourquoi l'utiliser ?
C'est un cadre de test robuste de style xUnit pour C/C++ avec une API propre, des macros d'assertion intégrées, une détection des fuites et un développement actif — idéal pour les systèmes hérités ou modernes.
Comment structurer un projet de base en utilisant CppUTest?
Comment exécutez-vous tous les tests ?
Le test runner utilise :
Comment construire des tests sans configurer manuellement les options du compilateur ?
Utilisez
MakefileWorker.mkde CppUTest, qui gère automatiquement les indicateurs, le lien et l'exécution des tests.CppUTest peut-il détecter les fuites de mémoire automatiquement ?
Oui. Cela remplace malloc/free lors des constructions de test, rapportant :
quel test a fui,
où cela s'est produit,
la taille de la fuite et le contenu de la mémoire.
Exemple de sortie d'échec :
Comment générer un code coverage ?
Activer :
CPPUTEST_USE_GCOV=YAssurez-vous que
filterGcov.shest disponible à$(CPPUTEST_HOME)/scripts/.Exécuter : make
gcovCela produit des rapports de couverture
.gcov, un résumé en texte, et des rapports de couverture HTML.
Que peut faire CppUTest d'autre au-delà des tests de base ?
système de simulation
système de plugins
scripts d'automatisation d'assistance
intégration native C
macros d'assertion étendues
Who is CppUTest best suited for?
Équipes travaillant avec des systèmes embarqués, des plateformes C, des services C++, ou tout environnement où la fiabilité et la sécurité mémoire doivent être continuellement validées.
Chez SparkPost, nous consacrons beaucoup de temps et d'efforts à tester notre code. Notre plateforme est écrite en C, et récemment, j'ai recherché l'intégration avec un framework de test unitaire appelé "CppUTest", qui fournit des tests de style xUnit pour C/C++. Ce framework est robuste, riche en fonctionnalités et en développement actif, ce qui en fait un excellent choix. Il offre également une couche d'intégration C qui rend son utilisation facile avec notre code C de plateforme même si la plupart du framework est en C++. Ce tutoriel couvre comment commencer avec CppUTest sur vos propres projets.
Téléchargement de CppUTest
La page du projet CppUTest est disponible sur le site officiel, et le dépôt est sur github. Il est également inclus dans les référentiels de gestion des paquets pour de nombreuses distributions Linux, ainsi que homebrew sur Mac OS. Les exemples qui suivent ont été exécutés sur Mac OS X, mais ils sont dérivés du code écrit pour Red Hat, le système d'exploitation sur lequel notre plateforme fonctionne.
Les bases sont bien documentées sur la page d'accueil de CppUTest. Nous allons survoler cela et passer à certaines des fonctionnalités les plus intéressantes.
Poser les bases
Projet Makefile
Le makefile du projet sera au même niveau que les répertoires ‘src’ et ‘t’ à la racine du projet. Il devrait ressembler à ceci :
Notez que cela utilise ‘make -C’ pour les cibles de test – ce qui signifie qu’il appellera ‘make’ à nouveau en utilisant le makefile dans le répertoire de test.
À ce stade, nous pouvons compiler le code ‘src’ avec le makefile et vérifier que cela fonctionne :
Tests Makefile
Pour les tests, les choses sont un peu plus compliquées car nous devons correctement charger et intégrer la bibliothèque CppUTest.
Le référentiel CppUTest fournit un fichier appelé « MakefileWorker.mk ». Il offre beaucoup de fonctionnalités qui facilitent la construction avec CppUTest. Le fichier se trouve dans le répertoire « build » du référentiel git. Pour ce tutoriel, nous allons supposer qu'il a été copié dans le répertoire ‘t/’. Il peut être utilisé comme suit :
Notez que CPPUTEST_HOME doit être défini à l'endroit où CppUTest a été installé. Si vous avez installé un package de distribution, ce sera généralement sous /usr/local sur un système linux/mac. Si vous avez récupéré le référentiel vous-même, c'est là où se trouve ce checkout.
Toutes ces options sont documentées dans MakefileWorker.mk.
MakefileWorker.mk ajoute également quelques cibles de makefile, y compris les suivantes :
all – construit les tests indiqués par le makefile
clean – supprime tous les fichiers d'objet et gcov générés pour les tests
realclean – supprime tous les fichiers d'objet ou gcov dans l'ensemble de l'arborescence de répertoires
flags – énumère tous les drapeaux configurés utilisés pour compiler les tests
debug – énumère tous les fichiers sources, objets, dépendances, et « choses à nettoyer »
Code Coverage
Les tests unitaires ne seraient pas complets sans un rapport de couverture. L'outil de référence pour cela, pour les projets utilisant gcc, est gcov, disponible dans le cadre de la suite standard des utilitaires gcc. Cpputest s'intègre facilement avec gcov, tout ce que vous devez faire est d'ajouter cette ligne au makefile :
CPPUTEST_USE_GCOV=Y
Ensuite, nous devons nous assurer que le script filterGcov.sh de ce repo soit dans ‘/scripts/filterGcov.sh’ par rapport à l'endroit où vous avez défini ‘CPPUTEST_HOME’. Il doit également avoir des permissions d'exécution.
Dans le Makefile d'exemple, il serait déployé dans ‘/usr/local/scripts/filterGcov.sh’. Si vous exécutez CppUTest à partir d'un checkout de repo, tout devrait fonctionner sans modification.
Avec cela en place, vous pouvez simplement exécuter ‘make gcov’ et l’analyse sera générée pour vous. Dans notre cas, nous devrons ‘make -B’ pour reconstruire les fichiers objets avec gcov activé :
Cela produira un certain nombre de fichiers dans un nouveau répertoire ‘gcov’. Ceux-ci sont :
code.cpp.gcov – le fichier ‘gcov’ réel pour le code testé
gcov_error.txt – un rapport d'erreur (dans notre cas, il devrait être vide)
gcov_output.txt – la sortie réelle de la commande gcov qui a été exécutée
gcov_report.txt – un résumé de la couverture pour chaque fichier testé
gcov_report.txt.html – une version html du rapport gcov
Cpputest Détection de fuite de mémoire
Cpputest vous permet de détecter automatiquement les fuites de mémoire en redéfinissant la famille de fonctions standard « malloc/free » pour utiliser ses propres enveloppes à la place. Cela lui permet de détecter rapidement les fuites et de les signaler pour chaque exécution de test. Ceci est activé par défaut dans MakefileWorker.mk, donc il est déjà en marche avec les étapes décrites jusqu'à présent.
Pour illustrer, faisons une fuite de mémoire dans test_func() !
Revenons à code.c, nous ajoutons un malloc() à la fonction, comme ceci :
Maintenant, après recompilation, l'erreur suivante est produite :
Cela montre quel test a causé la fuite, où la fuite s'est produite dans le code source, et ce qui se trouvait dans la mémoire fuyante. Très utile!
Il y a quelques mises en garde avec cette fonctionnalité :
Cpputest utilise des macros de préprocesseur pour redéfinir dynamiquement tous les appels aux fonctions de gestion de la mémoire standard. Cela signifie que cela ne fonctionnera que pour les appels dans le code source en test, car c'est ce qui est compilé avec les remplacements de CppUTest. Les fuites dans les bibliothèques liées ne seront pas détectées.
Parfois, la mémoire qui est allouée pour toute la durée de vie du processus n'est pas destinée à être libérée. Cela peut générer de nombreuses erreurs spammantes si vous testez un module avec ce comportement. Pour désactiver la détection des fuites, vous pouvez faire ceci :
CPPUTEST_USE_MEM_LEAK_DETECTION=N
Intéressé par More ?
Ceci n'est que la partie émergée de l'iceberg en ce qui concerne toutes les fonctionnalités contenues dans cet outil. Outre les bases discutées ici, il comprend également un cadre de simulation, une couche d'intégration C directe et un cadre de plugin, pour n'en nommer que quelques-uns parmi les plus importants. Le repo contient également un répertoire complet de scripts d'assistance qui peuvent aider à automatiser certaines des parties routinières du travail avec le framework.
J'espère que les informations ici vous aideront à améliorer la qualité de votre code C/C++ avec cet excellent outil !



