今天我們來說說,CMake 測(cè)試。
不過,其實(shí)我們還是在說 C++ 的測(cè)試。
CMake 給我們提供了完善的測(cè)試支持,比如它有一個(gè)專門的模塊 CTest。
CMake 原生測(cè)試支持
CMake 原生支持的測(cè)試很簡單,只有兩個(gè)函數(shù):
enable_testing()
add_test(NAME <name> COMMAND <command> [<arg>...]
[CONFIGURATIONS <config>...]
[WORKING_DIRECTORY <dir>]
[COMMAND_EXPAND_LISTS])
這個(gè)用法,簡單來說,就是你需要先實(shí)現(xiàn)一個(gè)可以接受輸入?yún)?shù)的可執(zhí)行程序,用 add_executable 就可以,不用管這個(gè)可執(zhí)行程序的存放目錄,CMake 會(huì)幫你自動(dòng)填上。
enable_testing()
add_executable(test_example test.cpp)
target_link_libraries(test_example example_lib)
add_test(NAME test_example1 COMMAND test_example --arg1=a --arg2=b)
add_test(NAME test_example2 COMMAND test_example --arg1=c --arg2=d)
然后,通過 add_test 注冊(cè)你的測(cè)試用例后,就完成了準(zhǔn)備,之后就可以在編譯完成后,用以下三種方式來運(yùn)行來運(yùn)行測(cè)試用例。
make testcmake --build . --target testctest
當(dāng)然了,你也可以用 CTest 來結(jié)合 CDash 一起使用,CDash 就是一個(gè)可以記錄測(cè)試日志的地方,你可以去 https://my.cdash.org/index.php 一探究竟,一般來說,項(xiàng)目大了之后就會(huì)有這方面的需求。
GoogleTest
除了上面的 ctest,我們還有強(qiáng)大的 GoogleTest,這是目前用得比較廣泛的 C++ 測(cè)試框架。不同于上面需要自己實(shí)現(xiàn)測(cè)試框架邏輯、解析參數(shù),GoogleTest 提供了測(cè)試框架,以及 Mock。
CMake 也提供了 GoogleTest 的支持:
gtest_add_tests(TARGET target
[SOURCES src1...]
[EXTRA_ARGS arg1...]
[WORKING_DIRECTORY dir]
[TEST_PREFIX prefix]
[TEST_SUFFIX suffix]
[SKIP_DEPENDENCY]
[TEST_LIST outVar]
)
它是用來取代 add_test 的,通過掃描源代碼,它就能讀出所有的測(cè)試用例,省卻了兩邊重復(fù)寫的問題,但是它有個(gè)問題:一旦測(cè)試用例改變,它就需要重新跑 cmake,不然無法知道改變后的測(cè)試用例。
因此,CMake 自從 3.10 提供了新的方法:
gtest_discover_tests(target
[EXTRA_ARGS arg1...]
[WORKING_DIRECTORY dir]
[TEST_PREFIX prefix]
[TEST_SUFFIX suffix]
[NO_PRETTY_TYPES] [NO_PRETTY_VALUES]
[PROPERTIES name1 value1...]
[TEST_LIST var]
[DISCOVERY_TIMEOUT seconds]
)
相比較于 gtest_add_tests,gtest_discover_tests 是通過獲取編譯后的可執(zhí)行程序里面的測(cè)試用例來達(dá)到注冊(cè)的目的,因此會(huì)更魯棒,在測(cè)試用例改變的情況下,不需要重新運(yùn)行 cmake(其實(shí)原理也不神奇,你用編譯后的程序運(yùn)行時(shí)加上 --gtest_list_tests 參數(shù)就明白了)。
使用也很簡單,在有 GoogleTest 依賴存在的情況下(不知道的需要復(fù)習(xí)前兩篇文章的內(nèi)容),通過 find_package 引入依賴。
enable_testing()
include(GoogleTest)
find_package(GTest 1.10.0)
add_executable(test test.cpp)
target_link_libraries(test GTest::gtest GTest::gtest_main GTest::gmock
GTest::gmock_main)
gtest_discover_tests(test)
至于 GoogleTest 本身,也就是看文檔寫測(cè)試用例了(有興趣的可以留言,有機(jī)會(huì)我另外寫一篇),另外,我之前在 Golang 中的測(cè)試 也提到過該如何寫單元測(cè)試,其實(shí)在這里道理也是一樣的,結(jié)合 GoogleTest 提供的 Mock,我們寫單元測(cè)試可以變得很簡單。
Ref
感謝閱讀,本文首發(fā)于 Github issues: https://github.com/xizhibei/blog/issues/136 (Star 以及 Watch 強(qiáng)烈暗示 :P);另外這篇文章也能在本人博客內(nèi)閱讀:https://blog.xizhibei.me/2020/04/05/cmake-4-test-with-google-test/ 。
本文采用 署名-非商業(yè)性使用-相同方式共享(BY-NC-SA)進(jìn)行許可。