CMake & CTest : make test는 테스트를 빌드하지 않습니다.


89

make testtarget을 사용하여 일부 테스트를 자동으로 실행하기 위해 CMake에서 CTest를 시도하고 있습니다. 문제는 CMake가 내가 실행하려는 테스트가 프로젝트의 일부이기 때문에 빌드되어야한다는 것을 "이해"하지 못한다는 것입니다.

그래서이 종속성을 명시 적으로 지정하는 방법을 찾고 있습니다.

답변:


79

그것은이다 틀림없이 CMake 버그 (이전 추적 여기 이 상자 밖으로 작동하지 않습니다)를. 해결 방법은 다음을 수행하는 것입니다.

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

그런 다음 make check실행할 수 있으며 테스트를 컴파일하고 실행합니다. 여러 테스트가 DEPENDS exe1 exe2 exe3 ...있는 경우 위 줄에서 사용해야 합니다.


1
그래서 "make test"대상은 add_custom_target 명령에서 다른 대상 이름을 선택해야하는 것처럼 보이기 때문에 사용되지 않는 상태로 유지 될 것 같습니다.
claf apr

네. "make test"와 "make check"의 유일한 차이점은 전자가 "Running tests ..."를 먼저 표시하고 빌드 종속성을 확인하지 않는다는 것입니다.
richq 2009

2
@rq-하지만 여러 프로젝트 (하나의 CMakeLists.txt가 다른 프로젝트의 하위 프로젝트 인 경우)에서 어떻게이 작업을 수행 할 수 있습니까? 그래서 각각은 check대상 을 정의 하고 충돌 할 수 있습니다
Artyom

2
@Artyom-이 경우 동등한 "make all test"를 사용하는 것이 더 좋습니다. 사실, 이것이 제가 어쨌든하는 일입니다.
richq

4
사실, 일부는 "메이크업 테스트"를 실행하고 단지 수 그것을 cmake의 기능 (안 버그)를 고려 실행 그들이 어떤 일을하지 않고 그대로 테스트를 ... 첫번째 재 - 구축
DLRdave

55

실제로 사용하는 방법이 있습니다 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)

11
이것은 확장되고 테스트를 실행하기 위해 "모두 만들기"대상을 빌드하도록 강요하지 않는 유일한 것입니다. 가능한 단점 : 바이너리의 빌드 오류에 대한 세부 정보는 생성 된 LastTest.log 파일에만 표시되고 stdout / stderr에는 표시되지 않습니다
Dave Abrahams

2
좋은 대답입니다! 그래도 빌드 대상에 구성을 추가해야합니다. 그렇지 않으면 모든 구성에서 테스트를 실행할 수 없습니다. add_test (NAME "$ {ARGV0} _BUILD"COMMAND "$ {CMAKE_COMMAND}"--build $ {CMAKE_BINARY_DIR} --target $ {target} "--config" "$ <CONFIG>")
Daniel

1
이것은 가짜 테스트로 테스트 리포터를 막습니다.

CMake> = 3.7을 사용하는 경우 권장되는 접근 방식은 조명기를 사용하는 것입니다. 아래 내 대답을 참조하십시오 .
John Freeman

13

나는 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입니다. 내가 밖으로의 나무 디버그 및 릴리스 (크로스 컴파일)를 호출하여 빌드를 수행하는 최상위 스크립트가 있기 때문에 내 경우에는, 그렇게 나쁘지 않아 cmake다음과를 make, 그리고 번역 testbuild_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

이 예에서 ctest 대신 ctest -V가 수행하는 작업을 수행하기 위해 make test를 얻는 방법이 있습니까? ctest 출력은 매우 불완전 해 보이며 단일 테스트가 있다고 말합니다.
Rajiv

6

에뮬레이트하려는 경우 다음 make check위키 항목이 유용 할 수 있습니다.

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

나는 그것이 성공으로 말하는 것을 방금 확인했습니다 (CMake 2.8.10).


1
이것은 실행할 때 모든 실행 파일을 빌드합니다 make check. 컴파일 시간이 지배적 인 테스트의 경우 이것은 ctest -R쓸모 가 없습니다.
usr1234567 2015-04-24

4

두통을 피하십시오.

make all test

나를 위해 즉시 작동하며 테스트를 실행하기 전에 종속성을 구축합니다. 이것이 얼마나 간단한 지 감안할 때 make test코드가 손상 되더라도 마지막 컴파일 테스트를 실행할 수있는 옵션을 제공하므로 네이티브 기능을 거의 편리하게 만듭니다 .


1
CDash에서는 작동하지 않습니다. make all && ctest를 호출해야하며 건물은 업로드 된 테스트의 일부가 아닙니다. 따라서 빌드 경고 또는 오류가 표시되지 않습니다.
usr1234567 2015-04-24

2
또한 병렬 빌드를 원하는 경우 두 가지가 병렬로 실행되므로 잘 작동하지 않습니다 make -j4 all && make test. 또한 비 Make 빌드 도구를 사용하는 경우에도 불안정합니다.
poolie

4

CMake> = 3.7을 사용하는 경우 권장되는 접근 방식은 fixtures 를 사용하는 것입니다 .

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

이것은 다음을 수행합니다.

  • test빌드 된 실행 가능한 타겟을 추가합니다.test.cpp
  • test_build타겟을 빌드하기 위해 Cmake를 실행 하는 "테스트"를 추가합니다.test
  • test_build테스트를 고정물의 설정 작업으로 표시합니다.test_fixture
  • 실행 파일 test만 실행 하는 테스트 추가test
  • test고정물이 필요한 테스트를 표시합니다 test_fixture.

따라서 테스트 test가 실행될 때마다 먼저 test_build필요한 실행 파일을 빌드하는 test를 실행합니다.


만약이 $<CONFIG>(가) 설정되지 않은 --target의 인수가 될 것이다 --config.
loshad vtapkah

나는 $<CONFIG>항상 비어 있지 않다고 믿습니다 . 구성 이름에 대한 생성기 표현식입니다. cmake.org/cmake/help/latest/manual/… 어쨌든 차이가 없다는 이유만으로 답을 따옴표로 묶도록 편집하겠습니다.
John Freeman

어떻게 뛰니 cmake? 나는 이렇게한다 : mkdir build; cd build; cmake ..; make. 그리고 CMAKE_BUILD_TYPE수동으로 설정할 때까지 기본값이없고 모든 관련 변수가 비어있는 것처럼 보입니다 . (현재 Debian 10에서는 다른 플랫폼을 확인하지 않았습니다.)
loshad vtapkah

1

이것이 내가 망치고 사용해온 것입니다.

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의 대답, 단순화 및 주석 :

# It is impossible to make target "test" depend on "all":
# https://gitlab.kitware.com/cmake/cmake/-/issues/8774
# Set a magic variable in a magic file that tells ctest
# to invoke the generator once before running the tests:
file(WRITE "${CMAKE_BINARY_DIR}/CTestCustom.cmake"
    "set(CTEST_CUSTOM_PRE_TEST ${CMAKE_MAKE_PROGRAM})\n"
)

ninja all test누군가 그렇게 할 경우 실행의 동시성 문제를 해결하지 못하기 때문에 완벽하게 정확하지 않습니다 . 반대로 지금은 두 개의 닌자 프로세스가 있기 때문입니다.

(Ftr, 여기 에서도이 솔루션을 공유했습니다 .)


-3

위의 모든 답변은 완벽합니다. 그러나 실제로 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 에서 확인하세요 .


5
때때로 실제로 실행되는 테스트에 필요한 대상 만 빌드하기를 원하기 때문에 비추천했습니다.
Dave Abrahams 2013

12
이 답변은 질문을 오해하는 것 같다 CTest, 사용 : 영업 이익은 이미 답이 권장 그대로하고있다 enable_testing(), add_test()문제는 그가 직접 테스트를 실행하기 전에 빌드 명령을 실행한다는 것이다, 등등. 그는 make test타겟이 필요에 따라 테스트 실행 파일을 자동으로 빌드하기를 원합니다 .
bames53

-4

모든 대답은 좋지만 명령에 의해 테스트를 실행하는 전통을 위반했음을 의미합니다 make test. 이 트릭을 수행했습니다.

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

이는 테스트가 실행 가능한 대상의 빌드 (선택 사항) 및 실행으로 구성됨을 의미합니다.


6
:-D 규칙 # 1 : sh없이 시스템을 사용하지 마십시오. 그런 시스템을 알고 있습니까?
dyomas

11
예, Windows는 이들 중 하나입니다.
David Faure 2015

3
이것은 또한 make다른 빌드 도구에 대한 스크립트를 생성하는 CMake의 기능에 하드 코딩되어 손실됩니다.
poolie
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.