cmake对任何编程语言进行测试
项目目录如下
.
├── CMakeLists.txt
├── main.cpp
├── sum_integers.cpp
├── sum_integers.hpp
├── test.cpp
├── test.py
└── test.sh
enable_testing()
启用test功能,测试该CMakeList.txt所在目录及其所有子文件夹。add_test()
定义一个新测试,并设置测试名称和运行命令例如:
add_test(
NAME cpp_test
COMMAND $
)
以便可以不显示的指定可执行程序的位置和名称,而且不同系统的可执行文件名可能不同,不好移植
再例如:
add_test(
NAME python_test_short
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test.py --short --executable $
)
构建一个名为python_test_short的测试项。调用python解释器,指定test.py的选项参数为–short, --executable , $
编译完后,执行ctest
命令即可进行测试。
--return-failed
执行之前失败的测试cmake还将为生成器创建目标。
make test
测试ninja test
测试例如:
add_test(
NAME python_test_long
COMMAND ${PYTHON_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/test.py --executable $
)
可以改写为如下,指定工作目录。
add_test(
NAME python_test_long
COMMAND ${PYTHON_EXECUTABLE} test.py --executable $
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
测试名称添加/
即可
add_test(
NAME python/long
COMMAND ${PYTHON_EXECUTABLE} test.py --executable $
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
)
set_tests_properties(python_test
PROPERTIES
ENVIRONMENT
ACCOUNT_MODULE_PATH=${CMAKE_CURRENT_SOURCE_DIR}
ACCOUNT_HEADER_FILE=${CMAKE_CURRENT_SOURCE_DIR}/account/account.h
ACCOUNT_LIBRARY_FILE=$
)
也可以通过CMAKE_COMMAND
调用CMake来预先设置环境变量。
add_test(
NAME
python_test
COMMAND
${CMAKE_COMMAND} -E env
ACCOUNT_MODULE_PATH=${CMAKE_CURRENT_SOURCE_DIR}
ACCOUNT_HEADER_FILE=${CMAKE_CURRENT_SOURCE_DIR}/account/account.h
ACCOUNT_LIBRARY_FILE=$
${PYTHON_EXECUTABLE}
${CMAKE_CURRENT_SOURCE_DIR}/account/test.py
)
Catch2是一个C++的测试框架。
git clone -b v3.3.2 https://github.com/catchorg/Catch2.git
cd Catch2
mkdir -p build&&cd build
cmake ..
make && make install
Catch2在cmake中的使用
find_package(Catch2 3 REQUIRED)
target_link_libraries(target_name
PRIVATE
Catch2::Catch2WithMain
)
enable_testing()
add_test(
NAME catch2_test
COMMAND $ --success
)
ctest -v //测试时输出详细信息
或
make test //如果构建器是unix makefile
也可以测试二进制文件,--success
是catch2的选项
./target_name --success
使用-h
可以查看Catch2提供的选项
./target_name --help
Google Test框架不仅仅是一个头文件,也是一个库,包含两个需要构建和链接的文件(gtest gtest_main gmock gmock_main)。
使用FetchContent
来获取第三方库,并链接。(不用安装,更加轻量级)。
include(FetchContent)
FetchContent_Declare(
googletest
GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG v1.13.0
)
#使gtest可用
FetchContent_MakeAvailable(googletest)
googletest在cmake中的使用
target_link_libraries(test_target
PRIVATE
gtest_main
)
enable_testing()
add_test(
NAME google_test
COMMAND $
)
Boost是c++社区非常流行的测试框架。
apt-get install libboost-all-dev
find_package(Boost 1.74 REQUIRED COMPONENTS unit_test_framework)
target_link_libraries(
test_target
PRIVATE
Boost::unit_test_framework
)
target_compile_definitions(
test_target
PRIVATE
BOOST_TEST_DYN_LINK
)
enable_testing()
add_test(
NAME boost_test
COMMAND $
)
make test //如果构建器为unix makefile
或
ctest -vv
内存缺陷:写入或读取越界,或者内存泄漏(已分配但从未释放的内存),会产生难以跟踪的bug
Valgrind 是一个通用的工具,用来检测内存缺陷和内存泄漏。
apt-get install valgrind
MEMORYCHECK_COMMAND
# 查找valgrind,并将MEMORYCHECK_COMMAND设置为其绝对路径
find_program(MEMORYCHECK_COMMAND NAMES valgrind)
# 将相关参数传递给valgrind
set(MEMORYCHECK_COMMAND_OPTIONS "--trace-children=yes --leak-check=full")
#显示添加CTest模块启用memcheck
include(CTest)
enable_testing()
add_test(
NAME test_target_name
COMMAND $
)
ctest -T memcheck
在某些情况,我们就是测试希望测试失败的测试项。即指定测试失败的项为成功。
# 将属性WILL_FAIL设置为true,将转换成功与失败
set_tests_properties(test_target PROPERTIES WILL_FAIL true)
如果需要更大的灵活性,可以将测试属性PASS_REGULAR_EXPRESSION
和FAIL_REGULAR_EXPRESSION
与set_tests_properties
组合使用。如果设置了这些参数,测试输出将根据参数给出的正则表达式列表进行检查,如果匹配了正则表达式,测试将通过或失败。
设置超时来终止耗时过长的测试。
# 超过10s即测试失败
set_tests_properties(test_target_name PROPERTIES TIMEOUT 10)
使用多核来减少测试时间。
执行测试时,可以使用以下命令,利用多核进行测试。
ctest --parallel N
或者在CMakeLists.txt中将CTEST_PARALLEL_LEVEL
设置为所需要的级别即可。
例如:
set(CTEST_PARALLEL_LEVEL 4)
set_tests_properties
来预先评估测试时间,以便cmake自动从最长的测试项开始测试。(即使时首次测试)例如:
set_tests_properties(
test_target
PROPERTIES COST 2.5
)
有时不需要运行所有测试项,可以使用测试子集。
ctest --parallel 4 -L myLabel
ctest --parallel 4 -R testName
ctest --parallel 4 -I 3,5
set_test_properties(
test_target
PROPERTIES
LABELS "myLabel"
)
有时在测试前需要进行某些操作,在测试完成后需要执行某些操作。这些都可以通过测试固件绑定测试项完成。
例如:
add_test(
NAME setup
COMMAND ${PYTHON_EXECUTABLE} setup.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test/
)
set_tests_properties(
setup
PROPERTIES
FIXTURES_SETUP my-fixture
)
add_test(
NAME feature-a
COMMAND ${PYTHON_EXECUTABLE} feature-a.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test/
)
add_test(
NAME feature-b
COMMAND ${PYTHON_EXECUTABLE} feature-b.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test/
)
set_tests_properties(
feature-a
feature-b
PROPERTIES
FIXTURES_REQUIRED my-fixture
)
add_test(
NAME cleanup
COMMAND ${PYTHON_EXECUTABLE} cleanup.py
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/test/
)
set_tests_properties(
cleanup
PROPERTIES
FIXTURES_CLEANUP my-fixture
)
FIXTURES_SETUP
和FIXTURES_CLEANUP
属性。FIXTURES_REQUIRED
)上述例子,在测试执行前会执行setup操作,测试完成后会执行cleanup操作。