前言

使用 C/C++ 开发的项目,在进行测试的时候,要么自己写一些简单的例子进行测试,要么使用第三方框架。自己写简单的例子对于大项目来说效率就不高,而且输出的结果就不是很专业,不能得到一个测试报告。

所以我们有必要选择一个比较好的测试框架来对代码进行测试,今天要介绍的就是谷歌的测试框架 google/googletest: GoogleTest - Google Testing and Mocking Framework

编译

在进行测试之前我们需要对 googletest 进行编译,然后集成到项目中,我们先来看看怎么编译。

只编译库文件

1
2
3
4
5
git clone https://github.com/google/googletest.git
cd googletest
mkdir build && cd build
cmake ..
make

编译生成的库文件在 lib 目录下,有了它和头文件就可以集成到项目中使用了。

编译samples

除了编译生成库文件, gtest 还提供了一些例子供我们学习,上面的编译并没有把 samples 也一起编译,可以通过如下命令编译 samples

1
cmake .. -Dgtest_build_samples=ON

编译好的二进制文件在 googletest 文件夹下,我们执行一个 sample1_unittest 看看效果

1
./googletest/sample1_unittest

输出结果如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
Running main() from ~/git/googletest/googletest/src/gtest_main.cc
[==========] Running 6 tests from 2 test suites.
[----------] Global test environment set-up.
[----------] 3 tests from FactorialTest
[ RUN      ] FactorialTest.Negative
[       OK ] FactorialTest.Negative (0 ms)
[ RUN      ] FactorialTest.Zero
[       OK ] FactorialTest.Zero (0 ms)
[ RUN      ] FactorialTest.Positive
[       OK ] FactorialTest.Positive (0 ms)
[----------] 3 tests from FactorialTest (0 ms total)

[----------] 3 tests from IsPrimeTest
[ RUN      ] IsPrimeTest.Negative
[       OK ] IsPrimeTest.Negative (0 ms)
[ RUN      ] IsPrimeTest.Trivial
[       OK ] IsPrimeTest.Trivial (0 ms)
[ RUN      ] IsPrimeTest.Positive
[       OK ] IsPrimeTest.Positive (0 ms)
[----------] 3 tests from IsPrimeTest (0 ms total)

[----------] Global test environment tear-down
[==========] 6 tests from 2 test suites ran. (0 ms total)
[  PASSED  ] 6 tests.

输出的结果很专业,并且对于通过和不通过是有颜色区分的,这里使用文本就看不出来了,大家可以自己尝试一下。

集成到自己的项目中使用

按照上面的步骤,我们已经编译好了 googletest 的库文件,现在就可以开始集成进项目中了,这里我就新创建一个 cmake 的工程了。

创建工程

1
2
3
4
5
6
mkdir test && cd test
mkdir src include libs
touch CMakeLists.txt
cp -r googletest/googletest/include/* include
cp -r build/lib/* libs
cd src && touch main.cpp

结构

创建好后,我们来看一下结构

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
.
├── CMakeLists.txt
├── include
│   └── gtest
│       ├── gtest-death-test.h
│       ├── gtest-matchers.h
│       ├── gtest-message.h
│       ├── gtest-param-test.h
│       ├── gtest-printers.h
│       ├── gtest-spi.h
│       ├── gtest-test-part.h
│       ├── gtest-typed-test.h
│       ├── gtest.h
│       ├── gtest_pred_impl.h
│       ├── gtest_prod.h
│       └── internal
│           ├── custom
│           │   ├── README.md
│           │   ├── gtest-port.h
│           │   ├── gtest-printers.h
│           │   └── gtest.h
│           ├── gtest-death-test-internal.h
│           ├── gtest-filepath.h
│           ├── gtest-internal.h
│           ├── gtest-param-util.h
│           ├── gtest-port-arch.h
│           ├── gtest-port.h
│           ├── gtest-string.h
│           └── gtest-type-util.h
├── libs
│   ├── libgmock.a
│   ├── libgmock_main.a
│   ├── libgtest.a
│   └── libgtest_main.a
└── src
    └── main.cpp

编写CMakeLists.txt

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
cmake_minimum_require(VERSION 2.8.12)

project(test)

set(CMAKE_CXX_STANDARD 11)

include_directories(${CMAKE_CURRENT_SOURCE_DIR}/include)

add_executable(test ${CMAKE_CURRENT_SOURCE_DIR}/src/main.cpp)

add_library(googletest SHARED IMPORTED)

set_target_properties(googletest PROPERTIES IMPORTED_LOCATION ${CMAKE_CURRENT_SOURCE_DIR}/libs/libgtest.a)

target_link_libraries(test googletest)

编写测试文件

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
#include <gtest/gtest.h>
#include <iostream>

int add(int a, int b) {
    return a + b;
}

TEST(test, add) {
    EXPECT_EQ(5, add(2, 3));
}

int main(int argc, char *argv[])
{
    std::cout << "start test" << std::endl;
    testing::InitGoogleTest();
    return RUN_ALL_TESTS();
}

执行

1
2
3
mkdir build && cd build
cmake ..
./test

执行的结果如下

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
start test
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from test
[ RUN      ] test.add
[       OK ] test.add (0 ms)
[----------] 1 test from test (0 ms total)

[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[  PASSED  ] 1 test.

总结

使用谷歌测试框架进行测试还是非常方便的。

首先我们需要编译出 libgtest 这个库,然后把头文件和库添加到项目中,这样就可以在项目中使用了。

参考