CMake & CTest: make test не создает тесты

Я пытаюсь использовать CTest в CMake, чтобы автоматически запускать некоторые мои тесты с помощью make test target. Проблема заключается в том, что CMake не "понимает", что тест, который я готов запустить, должен быть построен, поскольку он является частью проекта.

Итак, я ищу способ явно указать эту зависимость.

Ответ 1

Вероятно, это ошибка в CMake (ранее отслеживаемая здесь), что это не работает из коробки. Обходной путь заключается в следующем:

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

Затем вы можете запустить make check и он будет компилировать и запускать тест. Если у вас несколько тестов, вам нужно будет использовать DEPENDS exe1 exe2 exe3... в приведенной выше строке.

Ответ 2

На самом деле есть способ использовать make test. Вам нужно определить сборку тестового исполняемого файла как один из тестов, а затем добавить зависимости между тестами. То есть:

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)

Ответ 3

Я использую вариант ответа richq. На верхнем уровне CMakeLists.txt я добавляю пользовательскую цель build_and_test для создания и запуска всех тестов:

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

В различных файлах подпроекта CMakeLists.txt в разделе test/ я добавляю каждый тестовый исполняемый файл как зависимость от 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)

При таком подходе мне просто нужно make build_and_test вместо make test (или make all test), и он имеет преимущество только для создания тестового кода (и его зависимостей). Жаль, что я не могу использовать целевое имя test. В моем случае это не так уж плохо, потому что у меня есть верхний уровень script, который делает внеуровневые отладочные и выпущенные (и скомпилированные) сборки, вызывая cmake, а затем make, и он переводит test в build_and_test.

Очевидно, что материал GTest не требуется. Я просто использовал/как Google Test и хотел поделиться полным примером использования его с CMake/CTest. IMHO, этот подход также имеет преимущество, позволяя мне использовать ctest -V, который показывает результат теста Google во время тестов:

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

Ответ 4

Если вы пытаетесь эмулировать make check, вы можете найти эту запись в вики полезно:

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

Я только что проверил, что это делает то, что он говорит с успехом (CMake 2.8.10).

Ответ 5

Спасите себе головную боль:

make all test

Работает из коробки для меня и будет создавать зависимости перед запуском теста. Учитывая, насколько это просто, это почти делает функциональность родной make test удобной, поскольку она дает вам возможность запускать последние компиляционные тесты, даже если ваш код поврежден.

Ответ 6

Вот что я выбил и использовал:

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 \"@[email protected]\" 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

Ответ 7

Если вы используете CMake> = 3.7, то рекомендуется использовать приборы:

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)

Ответ 8

Все вышеприведенные ответы идеальны. Но на самом деле CMake использует CTest в качестве своих инструментов тестирования, поэтому стандартный метод (я думаю, это) для выполнения миссии:

enable_testing ()
add_test (TestName TestCommand)
add_test (TestName2 AnotherTestCommand)

Затем запустите cmake и сделать для создания целей. После этого вы можете запустить make test или просто запустить

ctest

вы получите результат. Это проверено в CMake 2.8.

Проверить информацию по адресу: http://cmake.org/Wiki/CMake/Testing_With_CTest#Simple_Testing

Ответ 9

Все ответы хороши, но они подразумевают нарушение традиции для запуска теста командой make test. Я сделал этот трюк:

add_test(NAME <mytest>
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND sh -c "make <mytarget>; $<TARGET_FILE:<mytarget>>")

Это означает, что тест состоит из построения (необязательно) и запуска исполняемого объекта.