介绍
使用CTest,你可以生成make test
目标来运行自动化单元测试。这个例子展示了如何找到Boost单元测试框架,创建测试并运行它们。
本教程中的文件如下:
$ tree
.
├── CMakeLists.txt
├── Reverse.h
├── Reverse.cpp
├── Palindrome.h
├── Palindrome.cpp
├── unit_tests.cpp
-
[CMakeLists.txt] - 包含要运行的CMake命令。
cmake_minimum_required(VERSION 3.5) # Set the project name project (boost_unit_test) # find a boost install with the libraries unit_test_framework find_package(Boost 1.46.1 REQUIRED COMPONENTS unit_test_framework) # Add an library for the example classes add_library(example_boost_unit_test Reverse.cpp Palindrome.cpp ) target_include_directories(example_boost_unit_test PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ) target_link_libraries(example_boost_unit_test PUBLIC Boost::boost ) ############################################# # Unit tests # enable CTest testing enable_testing() # Add a testing executable add_executable(unit_tests unit_tests.cpp) target_link_libraries(unit_tests example_boost_unit_test Boost::unit_test_framework ) target_compile_definitions(unit_tests PRIVATE BOOST_TEST_DYN_LINK ) add_test(test_all unit_tests)
-
[Reverse.h] / [.cpp] - 反转字符串的类。
#ifndef __REVERSE_H__ #define __REVERSE_H__ #include <string> /** * Trivial class whose only function is to reverse a string. * Should use std::reverse instead but want to have example with own class */ class Reverse { public: std::string reverse(std::string& toReverse); }; #endif
#include "Reverse.h" std::string Reverse::reverse(std::string& toReverse) { std::string ret; for(std::string::reverse_iterator rit=toReverse.rbegin(); rit!=toReverse.rend(); ++rit) { ret.insert(ret.end(), *rit); } return ret; }
-
[Palindrome.h] / [.cpp] - 测试字符串是否为回文的类。
#ifndef __PALINDROME_H__ #define __PALINDROME_H__ #include <string> /** * Trivial class to check if a string is a palindrome. */ class Palindrome { public: bool isPalindrome(const std::string& toCheck); }; #endif
#include "Palindrome.h" bool Palindrome::isPalindrome(const std::string& toCheck) { if (toCheck == std::string(toCheck.rbegin(), toCheck.rend())) { return true; } return false; }
-
[unit_tests.cpp] - 使用Boost单元测试框架的单元测试。
#include <string> #include "Reverse.h" #include "Palindrome.h" #define BOOST_TEST_MODULE VsidCommonTest #include <boost/test/unit_test.hpp> BOOST_AUTO_TEST_SUITE( reverse_tests ) BOOST_AUTO_TEST_CASE( simple ) { std::string toRev = "Hello"; Reverse rev; std::string res = rev.reverse(toRev); BOOST_CHECK_EQUAL( res, "olleH" ); } BOOST_AUTO_TEST_CASE( empty ) { std::string toRev; Reverse rev; std::string res = rev.reverse(toRev); BOOST_CHECK_EQUAL( res, "" ); } BOOST_AUTO_TEST_SUITE_END() BOOST_AUTO_TEST_SUITE( palindrome_tests ) BOOST_AUTO_TEST_CASE( is_palindrome ) { std::string pal = "mom"; Palindrome pally; BOOST_CHECK_EQUAL( pally.isPalindrome(pal), true ); } BOOST_AUTO_TEST_SUITE_END()
要求
此示例要求将Boost库安装在默认系统位置。
使用的库是Boost单元测试框架。
概念
启用测试
要启用测试,你必须在顶级CMakeLists.txt中包含以下行。
enable_testing()
这将启用对当前文件夹及其下面所有文件夹的测试。
添加测试可执行文件
此步骤的要求将取决于你的单元测试框架。在Boost的示例中,你可以创建包含要运行的所有单元测试的二进制文件。
add_executable(unit_tests unit_tests.cpp)
target_link_libraries(unit_tests
example_boost_unit_test
Boost::unit_test_framework
)
target_compile_definitions(unit_tests
PRIVATE
BOOST_TEST_DYN_LINK
)
在上面的代码中,添加了一个单元测试二进制文件,它链接到Boost单元测试框架,并包含一个定义来告诉它我们正在使用动态链接。
添加测试
要添加测试,可以调用add_test()
函数。这将创建一个命名测试,该测试将运行提供的命令。
add_test(test_all unit_tests)
在本例中,我们创建了一个名为test_all的测试,该测试将运行由调用add_executable
创建的unit_test可执行文件创建的可执行文件。
构建示例
$ mkdir build
$ cd build/
$ cmake ..
-- The C compiler identification is GNU 4.8.4
-- The CXX compiler identification is GNU 4.8.4
-- Check for working C compiler: /usr/bin/cc
-- Check for working C compiler: /usr/bin/cc -- works
-- Detecting C compiler ABI info
-- Detecting C compiler ABI info - done
-- Check for working CXX compiler: /usr/bin/c++
-- Check for working CXX compiler: /usr/bin/c++ -- works
-- Detecting CXX compiler ABI info
-- Detecting CXX compiler ABI info - done
-- Boost version: 1.54.0
-- Found the following Boost libraries:
-- unit_test_framework
-- Configuring done
-- Generating done
-- Build files have been written to: /home/matrim/workspace/cmake-examples/05-unit-testing/boost/build
$ make
Scanning dependencies of target example_boost_unit_test
[ 33%] Building CXX object CMakeFiles/example_boost_unit_test.dir/Reverse.cpp.o
[ 66%] Building CXX object CMakeFiles/example_boost_unit_test.dir/Palindrome.cpp.o
Linking CXX static library libexample_boost_unit_test.a
[ 66%] Built target example_boost_unit_test
Scanning dependencies of target unit_tests
[100%] Building CXX object CMakeFiles/unit_tests.dir/unit_tests.cpp.o
Linking CXX executable unit_tests
[100%] Built target unit_tests
$ make test
Running tests...
Test project /home/matrim/workspace/cmake-examples/05-unit-testing/boost/build
Start 1: test_all
1/1 Test #1: test_all ......................... Passed 0.00 sec
100% tests passed, 0 tests failed out of 1
Total Test time (real) = 0.01 sec
如果更改代码并导致单元测试产生错误。然后,在运行测试时,你将看到以下输出。
$ make test
Running tests...
Test project /home/matrim/workspace/cmake-examples/05-unit-testing/boost/build
Start 1: test_all
1/1 Test #1: test_all .........................***Failed 0.00 sec
0% tests passed, 1 tests failed out of 1
Total Test time (real) = 0.00 sec
The following tests FAILED:
1 - test_all (Failed)
Errors while running CTest
make: *** [test] Error 8