web-dev-qa-db-fra.com

CMake & CTest: make test ne construit pas de tests

J'essaie CTest dans CMake afin d'exécuter automatiquement certains de mes tests en utilisant make test target. Le problème est que CMake ne "comprend" pas que le test que je suis prêt à exécuter doit être construit car il fait partie du projet.

Je cherche donc un moyen de spécifier explicitement cette dépendance.

79
claf

C'est sans doute un bug dans CMake (précédemment suivi ici ) que cela ne fonctionne pas immédiatement. Une solution de contournement consiste à effectuer les opérations suivantes:

add_test(TestName ExeName)
add_custom_target(check COMMAND ${CMAKE_CTEST_COMMAND}
                  DEPENDS ExeName)

Ensuite, vous pouvez exécuter make check pour compiler et exécuter le test. Si vous avez plusieurs tests, vous devrez alors utiliser DEPENDS exe1 exe2 exe3 ... dans la ligne ci-dessus.

64
richq

Il y a en fait un moyen d'utiliser make test. Vous devez définir la construction de l'exécutable de test comme l'un des tests, puis ajouter des dépendances entre les tests. C'est:

ADD_TEST(ctest_build_test_code
         "${CMAKE_COMMAND}" --build ${CMAKE_BINARY_DIR} --target test_code)
ADD_TEST(ctest_run_test_code test_code)
SET_TESTS_PROPERTIES(ctest_run_test_code
                     PROPERTIES DEPENDS ctest_build_test_code)
47
Iakov

J'utilise une variante de la réponse de richq. Dans le CMakeLists.txt de niveau supérieur, j'ajoute une cible personnalisée, build_and_test, pour la création et l'exécution de tous les tests:

find_package(GTest)
if (GTEST_FOUND)
    enable_testing()
    add_custom_target(build_and_test ${CMAKE_CTEST_COMMAND} -V)
    add_subdirectory(test)
endif()

Dans les différents fichiers CMakeLists.txt du sous-projet sous test/, j'ajoute chaque exécutable de test en tant que dépendance de build_and_test:

include_directories(${CMAKE_SOURCE_DIR}/src/proj1)
include_directories(${GTEST_INCLUDE_DIRS})
add_executable(proj1_test proj1_test.cpp)
target_link_libraries(proj1_test ${GTEST_BOTH_LIBRARIES} pthread)
add_test(proj1_test proj1_test)
add_dependencies(build_and_test proj1_test)

Avec cette approche, il me suffit de make build_and_test au lieu de make test (ou make all test), qui présente l'avantage de ne générer que le code de test (et ses dépendances). C'est dommage que je ne puisse pas utiliser le nom de cible test. Dans mon cas, ce n’est pas si grave, car j’ai un script de niveau supérieur qui exécute des versions de débogage et de compilation (et de compilation croisée) en dehors de l’arbre en appelant cmake, puis make, et traduit test en build_and_test.

De toute évidence, le matériel GTest n'est pas nécessaire. Je viens d’utiliser/comme Google Test et je voulais partager un exemple complet de l’utiliser avec CMake/CTest. IMHO, cette approche a également l'avantage de me permettre d'utiliser ctest -V, qui affiche la sortie de Google Test pendant l'exécution des tests:

1: Running main() from gtest_main.cc
1: [==========] Running 1 test from 1 test case.
1: [----------] Global test environment set-up.
1: [----------] 1 test from proj1
1: [ RUN      ] proj1.dummy
1: [       OK ] proj1.dummy (0 ms)
1: [----------] 1 test from proj1 (1 ms total)
1:
1: [----------] Global test environment tear-down
1: [==========] 1 test from 1 test case ran. (1 ms total)
1: [  PASSED  ] 1 test.
1/2 Test #1: proj1_test .......................   Passed    0.03 sec
11
Trevor Robinson

Si vous essayez d'émuler make check, vous pouvez trouver cette entrée de wiki utile:

http://www.cmake.org/Wiki/CMakeEmulateMakeCheck

Je viens de vérifier que cela fait ce qu'il dit avec succès (CMake 2.8.10).

5
Samuel

Epargnez-vous le mal de tête:

make all test

Fonctionne hors de la boîte pour moi et construira des dépendances avant d'exécuter le test. Etant donné la simplicité de cette procédure, la fonctionnalité native make test est presque pratique, car elle vous permet d’exécuter les derniers tests de compilation même si votre code est cassé.

4
quant

C’est ce que j’ai martelé et que j’ai utilisé:

set(${PROJECT_NAME}_TESTS a b c)

enable_testing()
add_custom_target(all_tests)
foreach(test ${${PROJECT_NAME}_TESTS})
        add_executable(${test} EXCLUDE_FROM_ALL ${test}.cc)
        add_test(NAME ${test} COMMAND $<TARGET_FILE:${test}>)
        add_dependencies(all_tests ${test})
endforeach(test)

build_command(CTEST_CUSTOM_PRE_TEST TARGET all_tests)
string(CONFIGURE \"@CTEST_CUSTOM_PRE_TEST@\" CTEST_CUSTOM_PRE_TEST_QUOTED ESCAPE_QUOTES)
file(WRITE "${CMAKE_BINARY_DIR}/CTestCustom.cmake" "set(CTEST_CUSTOM_PRE_TEST ${CTEST_CUSTOM_PRE_TEST_QUOTED})" "\n")

YMMV

0
Derrick

Si vous utilisez CMake> = 3.7, l'approche recommandée consiste à utiliser fixtures :

add_executable(test test.cpp)
add_test(test_build
  "${CMAKE_COMMAND}"
  --build "${CMAKE_BINARY_DIR}"
  --config $<CONFIG>
  --target test
)
add_test(test test)
set_tests_properties(test       PROPERTIES FIXTURES_REQUIRED test_fixture)
set_tests_properties(test_build PROPERTIES FIXTURES_SETUP    test_fixture)
0
John Freeman