CMake & CTest: परीक्षण परीक्षण का निर्माण नहीं करता है


89

मैं make testलक्ष्य का उपयोग करके अपने कुछ परीक्षणों को स्वचालित रूप से चलाने के लिए सीएमके में सीटीस्ट की कोशिश कर रहा हूं । समस्या यह है कि सीमेक "समझ नहीं" है कि मैं जिस परीक्षण को चलाने के लिए तैयार हूं उसे परियोजना का हिस्सा होने के बाद बनाया जाना है।

इसलिए मैं इस निर्भरता को स्पष्ट रूप से निर्दिष्ट करने का एक तरीका ढूंढ रहा हूं।

जवाबों:


79

यह यकीनन सीएमके में एक बग (पहले यहां ट्रैक किया गया ) है कि यह बॉक्स से बाहर काम नहीं करता है। निम्नलिखित के लिए एक समाधान है:

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

फिर आप दौड़ सकते हैं make checkऔर यह परीक्षण को संकलित और चलाएगा। यदि आपके पास कई परीक्षण हैं, तो आपको DEPENDS exe1 exe2 exe3 ...उपरोक्त पंक्ति में उपयोग करना होगा ।


1
इसलिए मुझे लगता है कि "मेक टेस्ट" लक्ष्य अप्रयुक्त रहेगा क्योंकि ऐसा लगता है कि आपको एक अलग लक्ष्य नाम जोड़ना है ine_custom_target कमांड?
8

हां। "मेक टेस्ट" और "मेक चेक" के बीच एकमात्र अंतर है, पूर्व शो "रनिंग टेस्ट ..." पहले और किसी भी निर्भरता की जांच नहीं करता है।
ऋचीक

2
@rq - लेकिन मैं इसे कई प्रोजेक्ट्स के साथ कैसे कर सकता हूं (जब एक CMakeLists.txt दूसरे का सब-प्रोजेक्ट है) तो हर एक checkलक्ष्य को परिभाषित करेगा और वे टकरा सकते हैं
Artyom

2
@Artyom - उस स्थिति में आप शायद केवल "सभी परीक्षण करें" समकक्ष का उपयोग करने से बेहतर हैं। वास्तव में, यह वही है जो मैं वैसे भी करता हूं।
ऋक्

4
वास्तव में, कुछ इसे सीमेक की एक विशेषता (एक बग नहीं) मानते हैं जिसे आप "परीक्षण कर सकते हैं" और बस परीक्षणों को चला सकते हैं जैसे कि वे पहले कोई फिर से किए बिना कर रहे हैं ...
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 पर नहीं
डेव अब्राहम

2
अच्छा उत्तर! यद्यपि आपको बिल्ड लक्ष्य के लिए कॉन्फ़िगरेशन जोड़ना चाहिए। अन्यथा सभी कॉन्फ़िगरेशन में परीक्षण चलाना संभव नहीं है। add_test (NAME "$ {ARGV0} _BUILD" COMMAND "$ {CMAKE_COMMAND}" - $ $ {CMAKE_BINARY_DIR} --target $ {target} --config "" $ <CONFIG> ")
डैनियल

1
यह परीक्षण रिपोर्टर को फोनी परीक्षणों के एक समूह के साथ रोक देता है।

यदि आप CMake> = 3.7 का उपयोग कर रहे हैं, तो फिक्स्ड दृष्टिकोण जुड़नार का उपयोग करना है। देखें मेरा उत्तर नीचे।
जॉन फ्रीमैन

13

मैं रिचट के उत्तर के एक संस्करण का उपयोग करता हूं। शीर्ष-स्तर में 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, और इसका अनुवाद testकरता है build_and_test

जाहिर है, GTest सामान की आवश्यकता नहीं है। मैं केवल Google टेस्ट का उपयोग / पसंद करना चाहता हूं, और इसे 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 क्या करता है, इसके लिए टेस्ट कराने का एक तरीका है? Ctest आउटपुट बहुत अधूरा लगता है और बस यही कहता है कि एक ही टेस्ट है।
राजीव

6

यदि आप अनुकरण करने की कोशिश कर रहे हैं make check, तो आपको यह विकि प्रविष्टि उपयोगी मिल सकती है:

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

मैंने अभी-अभी जाँच की है कि यह सफलता के साथ क्या कहता है (CMake 2.8.10)।


1
यह चलने पर सभी निष्पादन योग्य का निर्माण करेगा make check। संकलन समय के साथ परीक्षण के लिए, यह ctest -Rबेकार बना देता है ।
usr1234567

4

अपने आप को सिरदर्द से बचाएं:

make all test

मेरे लिए बॉक्स से बाहर काम करता है और परीक्षण चलाने से पहले निर्भरता का निर्माण करेगा। यह देखते हुए कि यह कितना सरल है, यह लगभग देशी make testकार्यक्षमता को सुविधाजनक बनाता है क्योंकि यह आपको अंतिम संकलन परीक्षणों को चलाने का विकल्प देता है, भले ही आपका कोड टूट गया हो।


1
CDash के साथ काम नहीं करता है। आपको कॉल करना है सभी && ctest और फिर भवन अपलोड किए गए परीक्षण का हिस्सा नहीं है। इसलिए चेतावनियों या त्रुटियों का निर्माण न करें।
usr1234567

2
यदि आप एक समानांतर निर्माण चाहते हैं तो भी अच्छी तरह से काम नहीं करता है, क्योंकि दोनों समानांतर में चलेंगे: आपको जरूरत है make -j4 all && make test। और यह गैर-निर्मित बिल्ड टूल का उपयोग करके भी परतदार है।
पूलि

4

यदि आप CMake> = 3.7 का उपयोग कर रहे हैं, तो फिक्स्चर का उपयोग करने के लिए अनुशंसित दृष्टिकोण है :

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, जो आवश्यक निष्पादन योग्य बनाता है।


यदि $<CONFIG>सेट नहीं किया जाता है तो --targetइसके लिए तर्क बन जाएगा --config
लोसड वटपक्खा

मेरा मानना $<CONFIG>है कि हमेशा गैर-खाली रहता है। यह कॉन्फ़िगरेशन नाम के लिए एक जनरेटर अभिव्यक्ति है: cmake.org/cmake/help/latest/manual/… मैं इसे उद्धरण में लपेटने के उत्तर को वैसे भी संपादित करूंगा क्योंकि इससे कोई फर्क नहीं पड़ता।
जॉन फ्रीमैन

तुम कैसे दौड़ोगे cmake? मैं इस तरह से करता हूं mkdir build; cd build; cmake ..; make:। और ऐसा लगता है कि कोई भी चूक नहीं है और सभी संबंधित चर खाली हैं, जब तक CMAKE_BUILD_TYPEकि मैन्युअल रूप से सेट नहीं किया जाता है। (वर्तमान में डेबियन 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

डेरिक का जवाब, सरल और टिप्पणी:

# 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, अगर कोई ऐसा करता है। इसके विपरीत, क्योंकि अब, आपके पास दो निंजा प्रक्रियाएं हैं।

(फीट, मैंने यह समाधान भी यहां साझा किया है ।)


-3

उपरोक्त सभी उत्तर परिपूर्ण हैं। लेकिन वास्तव में CMake अपने परीक्षण उपकरण के रूप में CTest का उपयोग करते हैं, इसलिए मिशन करने के लिए मानक विधि (मुझे लगता है कि यह है):

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

फिर cmake चलाएं और लक्ष्य बनाने के लिए करें। उसके बाद, आप या तो परीक्षण बना सकते हैं , या बस चला सकते हैं

ctest

आपको इसका परिणाम मिलेगा। यह CMake 2.8 के तहत परीक्षण किया गया है।

विवरण यहां देखें: http://cmake.org/Wiki/CMake/Testing_With_CTest#Simple_Testing


5
नीच क्योंकि कभी-कभी आप केवल वास्तव में चलाए जा रहे परीक्षणों के लिए आवश्यक लक्ष्यों का निर्माण करना चाहते हैं।
डेव अब्राहम

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: श के बिना सिस्टम का उपयोग न करें। क्या आप ऐसी व्यवस्था जानते हैं?
डियोमास

11
हां, विंडोज इनमें से एक है।
डेविड फेवर

3
यह makeसीएमके द्वारा अन्य बिल्ड टूल्स के लिए स्क्रिप्ट बनाने की सुविधा को भी खो देता है।
poolie
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.