【Cmake】Ctest测试工具
目录
前言
原文:CTest - https://www.cnblogs.com/457220157-FTD/p/4139149.html
一、初识CTest
CTest是CMake集成的一个测试工具,在使用CMakeLists.txt文件编译工程的时候,CTest会自动configure、build、test和展现测试结果
CTest有两个模式:
- 模式一: 使用CMake configure 和 build工程,在CMakeLists.txt文件中,使用特殊的命令取创建tests。CTest用来执行那些测试
- 模式二: 使用CTest来执行一个script(这个script的语法必须和CMakeLists.txt相同),去控制整个程序的输出结果=
二、使用方法
目前我们在工程中这样构建单元测试
project |--------include | |--------src | |-----------test | |---CMakeLists.txt | |--------CMakeLists.txt
1. 在外面的CMakeLists.txt中我们这样写
cmake_minimum_required(VERSION 2.8) project(test)#指定工程名 .... add_subdirectory(test)#递归进入test目录 enable_testing()#见附录1 可以开启项目的测试功能。一定要在根目录下的CMakeLists.txt中开启 add_test(NAME mytest COMMAND Test)#见附录1
2. 在test/CMakeLists.txt中写你的测试需要的即可(可以如下面那样写)
三、完整的简单测试工程
include
//sqr.h
#ifndef SQR_H_
#define SQR_H_
double sqr(double);
#endif
src #我们的工程代码
//sqr.cpp
#include "sqr.h"
double sqr(double x) {
return x * x;
}
//main.cpp
int main()
{
return 0;
}
test #Ctest的代码,测试我们的工程函数
//test.cpp
#include "sqr.h"
#define BOOST_TEST_MODULE SqrTests
#include <boost/test/unit_test.hpp>
BOOST_AUTO_TEST_CASE(FailTest)
{
BOOST_CHECK_EQUAL(5, sqr(2));
}
BOOST_AUTO_TEST_CASE(PassTest)
{
BOOST_CHECK_EQUAL(4, sqr(2));
}
//CMakeLists.txt
find_package(Boost COMPONENTS system filesystem unit_test_framework REQUIRED)
include_directories(include ${Boost_INCLUDE_DIRS}/boost)
add_definitions(-DBOOST_TEST_DYN_LINK -g)
add_executable(Test test.cpp)
target_link_libraries(Test sqr ${Boost_FILESYSTEM_LIBRARY}
${Boost_SYSTEM_LIBRARY}
${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
message(WARNING ${Boost_FILESYSTEM_LIBRARY})
message(WARNING ${Boost_SYSTEM_LIBRARY})
message(WARNING ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY})
CMakeLists.txt #test的CMakeLists
cmake_minimum_required(VERSION 2.8)
project(test)
include_directories(include)
add_library(sqr STATIC src/sqr.cpp)
add_executable(demo src/main.cpp)
target_link_libraries(demo sqr)
add_subdirectory(test)
enable_testing()
add_test(NAME mytest COMMAND Test)
简单例子说明
通过在项目根目录下的CMakeLists.txt配置文件中添加
enable_testing()
可以开启项目的测试功能。一定要在根目录下的CMakeLists.txt中开启,不然执行make test时会报错。
随后项目的cmake配置文件中可以添加add_test指令
add_test(NAME <name> [CONFIGURATIONS [Debug|Release|...]]
[WORKING_DIRECTORY dir]
COMMAND <command> [arg1 [arg2 ...]])
其中通过NAME关键值指定本测试的名称,可以随意命名,
Debug/Release选项可以控制在不同的编译版本下是否进行测试。
通过WORKING_DIRECTORY可以设置工作路径,command表示可运行程序
比如:
ADD_TEST(NAME test1 COMMAND main)
你可以不对结果进行检查,但大多数情况下你都需要检查test1的输出结果,可以通过如下:
set_tests_properties(test1 PROPERTIES PASS_REGULAR_EXPRESSION "Hello Cmake")
运行cmake && make test结果如下:
Start 1: test1
1/1 Test #1: test1 ............................ Passed 0.00 sec100% tests passed, 0 tests failed out of 1
如果失败的话,也会有提示
Start 1: test1
1/1 Test #1: test1 ............................***Failed Required regular expression not found.Regex=[Hello
] 0.00 sec0% tests passed, 1 tests failed out of 1
原文链接:https://blog.csdn.net/sun_ashe/article/details/104527591/
示例2
CMakeCTest简单示例 -https://wenku.baidu.com/view/12bb3c49bb4ae45c3b3567ec102de2bd9605de82.html
cmake命令之add_test和set_tests_properties使用案例
(摘自:https://blog.csdn.net/weixin_42108533/article/details/119220713)
add_test的命令形式如下
add_test(NAME <name> COMMAND <command> [<arg>...]
[CONFIGURATIONS <config>...]
[WORKING_DIRECTORY <dir>]
[COMMAND_EXPAND_LISTS])
set_tests_properties的命令形式如下
set_tests_properties(test1 [test2...]
PROPERTIES prop1 value1 prop2 value2)
我见过的cmake工具测试的套路之一如下
- 首先,启动测试 enable_testing()
(开启项目的测试功能。一定要在根目录下的CMakeLists.txt中开启,不然执行make test时会报错。)
- 其次,add_test(...)
- 接下来,set_tests_properties(...)
案例目录如下
├── build
├── CMakeLists.txt
└── main.cpp
main.cpp的内容如下
#include<stdlib.h>
#include<stdio.h>
using namespace std;
int sum(int a, int b)
{
return a + b;
}
int main(int argc, char *argv[])
{
if(3 == argc)
{
cout << "parameter right" << endl;
cout << sum(atoi(argv[1]), atoi(argv[2])) << endl;
}
else
{
cout << "input num err" << endl;
return -1;
}
return 0;
}
CMakeLists.txt的内容如下
#最小版本说明
CMAKE_MINIMUM_REQUIRED(VERSION 3.10)
#项目信息
PROJECT(main)
#生成可执行文件
ADD_EXECUTABLE(main main.cpp)
#使能测试
enable_testing()
#添加测试
add_test(demo_test main 2 3)
#设定测试特性
set_tests_properties(demo_test PROPERTIES PASS_REGULAR_EXPRESSION "5")
build是编译目录,方便编译出错时,清除生成的缓存文件
cd build //进入编译目录
cmake .. //编译主目录的CMakeLists.txt
make //编译生成的MakeFile.txt
make test //执行CMakeLists.txt里的测试
执行结果如下图所示
参考文献如下
cmake的帮助文档的网址
CMake Reference Documentation — CMake 3.21.7 Documentation
附录
附录一 cmake命令
enable_testing
可以开启项目的测试功能。
一定要在根目录下的CMakeLists.txt中开启,不然执行make test时会报错。
添加对TestingDashboard的支持
在之前已经定义了项目对测Test的支持,现在只需要将那些Test上传到Dashboard。
在上层CMakeLists.txt中将
# enable testing
enable_testing()
替换成
# enable dashboard scripting
include(CTest)
CTest模块将自动调用enable_testing().
创建CTestConfig.cmake在上层目录中,在cmake文件中,我们可以声明项目的名字和上传到的地址。在cmake文件中,添加如下内容:
set(CTEST_PROJECT_NAME "CMakeTutorial")
set(CTEST_NIGHTLY_START_TIME "00:00:00 EST")set(CTEST_DROP_METHOD "http")
set(CTEST_DROP_SITE "my.cdash.org")
set(CTEST_DROP_LOCATION "/submit.php?project=CMakeTutorial")
set(CTEST_DROP_SITE_CDASH TRUE)
当ctest运行时将读取这个文件。
cmake完成之后,运行以下指令将测试上传到Dashboard:
ctest [-VV] -D Experimental
利用-C选项设置生成器:
ctest [-VV] -C Debug -D Experimental
可以在https://my.cdash.org/index.php?project=CMakeTutorial.查看测试结果。
原文链接:https://blog.csdn.net/xu_yun_huan_yue/article/details/120155307
add_test
该命令将目标(或自定义命令)添加到CTest。因此,当您在build目录中执行ctest
时,所有添加的测试都会执行。如果您不想使用CTest,而只是手动执行测试二进制文件,那么就没有必要使用add_test
。
在较大的项目中,测试通常由几个二进制文件组成,使用单个命令执行所有测试会更方便(特别是当您的构建管道是自动化的时候)。
CMake的CTest方法
PART 1:
参考:http://hahack.com/codes/cmake/
Demo目录结构如下:
Test/
├── add.cpp
└── CMakeLists.txt
add.cpp
#include <iostream>
#include <stdlib.h>
int main(int argc, char *argv[])
{
if (argc != 3) {
std::cout << "parameter error" << std::endl;
return -1;
}
int a, b;
a = atoi(argv[1]);
b = atoi(argv[2]);
std::cout << a << " + " << b << " is " << a + b << std::endl;
return 0;
}
CMakeLists.txt
CMAKE_MINIMUM_REQUIRED(VERSION 3.3)
ADD_EXECUTABLE(add add.cpp)
enable_testing()
ADD_TEST(NAME test_add_2_3 COMMAND add 2 3)
SET_TESTS_PROPERTIES(test_add_2_3
PROPERTIES PASS_REGULAR_EXPRESSION "5")
ADD_TEST(NAME test_add_4_5 COMMAND add 4 5)
SET_TESTS_PROPERTIES(test_add_4_5
PROPERTIES PASS_REGULAR_EXPRESSION "9")
在CMakeLists.txt里面,我们添加了两个测试用例。其中 PASS_REGULAR_EXPRESSION 用来测试输出是否包含后面的字符串。
在Test目录下建立build目录,cd build && cmake .., make, make test, 结果如下:
huyanjie@debian:~/test/Test/build$ make test
Running tests...
Test project /home/huyanjie/test/Test/build
Start 1: test_add_2_3
1/2 Test #1: test_add_2_3 ..................... Passed 0.00 sec
Start 2: test_add_4_5
2/2 Test #2: test_add_4_5 ..................... Passed 0.00 sec
100% tests passed, 0 tests failed out of 2
Total Test time (real) = 0.01 sec
可以看到两个用例都正确执行了。
像上面的方式写测试用例还是比较繁琐,还可以定义宏来简化:
CMAKE_MINIMUM_REQUIRED(VERSION 3.3)
ADD_EXECUTABLE(add add.cpp)
enable_testing()
macro(do_test ARG1 ARG2 RESULT)
ADD_TEST(NAME test_add_${ARG1}_${ARG2} COMMAND add ${ARG1} ${ARG2})
SET_TESTS_PROPERTIES(test_add_${ARG1}_${ARG2}
PROPERTIES PASS_REGULAR_EXPRESSION ${RESULT})
endmacro(do_test)
do_test(2 3 5)
do_test(4 5 9)
PART 2:
CPPUNIT使用如下:
参考http://blog.csdn.net/freefalcon/article/details/753819
#include <cppunit/TestResult.h>
#include <cppunit/TestResultCollector.h>
#include <cppunit/TextOutputter.h>
#include <cppunit/TestRunner.h>
#include <cppunit/extensions/HelperMacros.h>
class StringTest : public CppUnit::TestFixture
{
CPPUNIT_TEST_SUITE(StringTest);
CPPUNIT_TEST(testSwap);
CPPUNIT_TEST(testFind);
CPPUNIT_TEST_SUITE_END();
public:
void setUp()
{
m_str1 = "Hello, world";
m_str2 = "Hi, cppunit";
}
void tearDown()
{
}
void testSwap()
{
std::string str1 = m_str1;
std::string str2 = m_str2;
m_str1.swap(m_str2);
CPPUNIT_ASSERT(m_str1 == str2);
CPPUNIT_ASSERT(m_str2 == str2);
}
void testFind()
{
int pos1 = m_str1.find(',');
int pos2 = m_str2.rfind(',');
CPPUNIT_ASSERT_EQUAL(5, pos1);
CPPUNIT_ASSERT_EQUAL(2, pos2);
}
protected:
std::string m_str1;
std::string m_str2;
};
CPPUNIT_TEST_SUITE_REGISTRATION(StringTest);
int main(int argc, char *argv[])
{
CppUnit::TestResult r;
CppUnit::TestResultCollector rc;
r.addListener(&rc);
CppUnit::TestRunner runner;
runner.addTest(CppUnit::TestFactoryRegistry::getRegistry().makeTest());
runner.run(r);
CppUnit::TextOutputter o(&rc, std::cout);
o.write();
return rc.wasSuccessful()?0:-1;
}
PART 3
CMake 结合CPPUnit
原文链接:https://blog.csdn.net/huyanjie0327/article/details/46652313