J'exécute des tests unitaires en construisant avec ninja
puis en exécutant ninja test
de mon arbre de génération:
cmake -G Ninja /source/tree
ninja
ninja test
Cependant, pour exécuter valgrind, je dois l'exécuter manuellement:
valgrind rel/path/to/test
J'aimerais que valgrind
s'exécute automatiquement lorsque j'exécute ninja test
. Selon la documentation de cmake "la configuration des [tests valgrind] est extrêmement facile " mais quand je cours
ctest -D NightlyMemoryCheck
Je reçois juste cette erreur:
Cannot find file: /home/arman/tinman/deb/DartConfiguration.tcl
Site:
Build name: (empty)
WARNING: No nightly start time found please set in CTestConfig.cmake or DartConfig.cmake
Problem initializing the dashboard.
J'obtiens une erreur similaire lorsque je suis les instructions de cette SO question:
Comment puis-je faire ctest exécuter un programme avec valgrind sans fléchette?
Je ne sais pas ce qu'est Dart
, mais selon le site Web, c'est une sorte de test en ligne.
Clairement extrêmement facile n'est pas assez facile pour moi. Est-ce que quelqu'un connaît une solution si extrêmement simple qu'il faudrait être une sorte de démoniste informatique pour que ça fonctionne pas?
Voici un exemple autonome qui montre comment ajouter des tests valgrind à un projet CMake. L'exemple consiste en un seul fichier source C++ main.cpp
:
#include <iostream>
int main()
{
double* leak = new double[10];
std::cout << "Hello!" << std::endl;
}
Le code contient une fuite intentionnelle qui devrait être détectée par valgrind. Nous avons également besoin d'un fichier CMakeLists.txt
Qui nécessite CMake> = 2.8:
cmake_minimum_required(VERSION 2.8)
project (ValgrindExample)
include (CTest)
add_executable(example main.cpp)
add_test(example_test example)
Ici, il est important d'inclure le module CTest avec include
au lieu d'activer simplement les tests avec enable_testing()
. Le module CTest prend en charge la configuration de la machine pour pouvoir exécuter des contrôles de mémoire avec des tests (par exemple, il localise l'exécutable valgrind).
Nous pouvons maintenant ouvrir une session Shell dans le dossier du projet et créer une arborescence de construction Ninja:
$ mkdir build; cd build
$ cmake -G Ninja -DCMAKE_BUILD_TYPE=Debug ..
Nous pouvons construire et exécuter des tests sans valgrind de manière régulière:
$ ninja
[2/2] Linking CXX executable example
$ ninja test
[0/1] Running tests...
...
100% tests passed, 0 tests failed out of 1
Total Test time (real) = 0.01 sec
Pour exécuter des tests avec valgrind, nous devons utiliser l'exécutable ctest de CMake avec l'action de test memcheck
:
$ ctest -T memcheck
...
1/1 MemCheck #1: example_test ..................... Passed 0.77 sec
100% tests passed, 0 tests failed out of 1
Total Test time (real) = 0.77 sec
-- Processing memory checking output:
Memory checking results:
Memory Leak - 2
ctest imprime un résumé des résultats de la vérification de la mémoire. La sortie détaillée de valgrind se trouve dans un répertoire temporaire dans l'arborescence de construction:
$ cat ./Testing/Temporary/MemoryChecker.*.log
==4565== 80 bytes in 1 blocks are definitely lost in loss record 37 of 64
==4565== at 0x10000B681: malloc (in /usr/local/Cellar/valgrind/3.12.0/lib/valgrind/vgpreload_memcheck-AMD64-darwin.so)
==4565== by 0x1000507DD: operator new(unsigned long) (in /usr/lib/libc++.1.dylib)
==4565== by 0x100000F93: main (main.cpp:5)
...
Il n'est pas possible d'exécuter automatiquement valgrind lorsque vous exécutez ninja test
Car la cible de test intégrée de CMake ne peut pas être modifiée et exécute toujours les tests de manière régulière. Nous pouvons cependant ajouter une cible CMake personnalisée qui invoque ctest avec l'option -T memcheck
Puis imprime le rapport détaillé de valgrind:
add_custom_target(test_memcheck
COMMAND ${CMAKE_CTEST_COMMAND}
--force-new-ctest-process --test-action memcheck
COMMAND cat "${CMAKE_BINARY_DIR}/Testing/Temporary/MemoryChecker.*.log")
--test-action
Est la version détaillée du commutateur -T
.
Nous pouvons alors invoquer les tests valgrind de Ninja avec
$ ninja test_memcheck
et obtenez les résultats comme si nous exécutions valgrind manuellement.