CMake 除了提供自动编译的工具之外,还可以用来进行测试,提供了一整套基于 ctest 的工具。
使用简介
可以通过如下方式添加测试用例。
OPTION(WITH_UNIT_TESTS "Compile with unit tests" OFF)
# Setup testing
IF(WITH_UNIT_TESTS)
ENABLE_TESTING()
ADD_SUBDIRECTORY(test)
ENDIF()
# test/CMakeLists.txt
FILE(GLOB SRCS *.c)
ADD_EXECUTABLE(testfoo ${SRCS})
TARGET_LINK_LIBRARIES(testfoo libs)
ADD_TEST(
NAME testfoo
COMMAND testfoo your arguments
)
然后在编译时通过 cmake .. -DWITH_UNIT_TESTS=ON
执行,并通过 make test
进行测试,实际等价于在 build
目录下运行 ctest
命令。
另外,可以指定测试的参数,以及输出的匹配。
ADD_TEST(test foobar 10 5)
SET_TESTS_PROPERTIES(test PROPERTIES PASS_REGULAR_EXPRESSION "ok")
对于 valgrind,如果输出是 reachable 类型,那么实际上是依赖于 OS 的内存回收,此时及时已经配置了 --error-exitcode=1
也不会返回 0 ,尤其是对于全局变量。
为此,对于 CMake 而言,就需要配置 FAIL_REGULAR_EXPRESSION "reachable"
,这样对其它内存泄露也会报错。
SetUp TearDown
一般在测试用例中会存在 SetUp 以及 TearDown ,分别用来做一些测试前后的准备工作,除此之外,还有一种方式 Fixture ,也就是打桩。
相比来说,打桩的处理流程会更加复杂,通常为了方便管理,会将测试相关的内容单独抽象一层。
CMAKE_MINIMUM_REQUIRED(VERSION 3.7)
PROJECT(foo)
ENABLE_TESTING()
#ADD_TEST(NAME DBSetUp COMMAND /usr/bin/false)
ADD_TEST(NAME DBSetUp COMMAND ${CMAKE_COMMAND} -E echo setup)
ADD_TEST(NAME DBCleanUp COMMAND ${CMAKE_COMMAND} -E echo cleanup)
ADD_TEST(NAME TCaseFoo COMMAND ${CMAKE_COMMAND} -E echo "Needs Fixture Foo")
ADD_TEST(NAME TCaseBar COMMAND ${CMAKE_COMMAND} -E echo "Needs Fixture Bar")
# Specified multi dependences, like "DB;File"
SET_TESTS_PROPERTIES(TCaseFoo TCaseBar
PROPERTIES FIXTURES_REQUIRED DB)
SET_TESTS_PROPERTIES(DBSetUp PROPERTIES FIXTURES_SETUP DB)
SET_TESTS_PROPERTIES(DBCleanUp PROPERTIES FIXTURES_CLEANUP DB)
SET_TESTS_PROPERTIES(DBSetUp DBCleanUp TCaseFoo TCaseBar
PROPERTIES RESOURCE_LOCK SerialDB
)
在运行一堆的测试用例之前,需要准备一些资源,最常见的是 DB 相关的数据。
----- 运行指定的测试用例
$ ctest -R <TEST_NAME>
----- 重新运行失败的用例
$ ctest --rerun-failed
如果通过 ctest 单独测试某个用例,ctest 会先根据配置生成相关的依赖,如果 SetUp 执行失败会跳过相关的测试用例 (注意,清理函数还会继续执行) 。
当已经完成测试,可以通过 ctest -R cleanup
执行清理操作。
默认各个测试是并发执行的,如果需要串行执行,可以通过 RESOURCE_LOCK
来实现。
其它
超时设置
可以针对单个测试用例设置超时时间,单位是秒。
ADD_TEST(yourtest ...)
SET_TESTS_PROPERTIES(yourtest PROPERTIES TIMEOUT 30)
另外,如果单独使用 ctest 进行测试,那么可以在启动的时候添加 --timeout 120
参数,指定默认的超时时间。