这里以 cpplib_base 项目集成gtest为例,说明如何快速将gtest应用到我们自己的项目中.

1. 集成googletest

对于git管理的项目,我们可以使用submodule将gtest作为子模块集成到我们的项目中:

git submodule add https://github.com/google/googletest.git src/base/third_party/googletest

这条命令会将googletest项目作为我们的子模块,存放路径是当前项目下的src/base/third_party/googletest,也就是代码同步后gtest代码存放的位置,在项目的.gitmodules文件中就能看到它的信息.使用以下命令同步子模块的代码:

git submodule update --init --recursive

进入到googletest目录下可以看到它是可以通过cmake编译出来的,因此我们自己的项目中可以使用add_subdirectory的方法快速编译子模块.
在自己项目的CMakeLists.txt中加入

#Unit test add_subdirectory(src/base/third_party/googletest) enable_testing() include_directories(${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})

如此,就可以编译出gtest静态库和引入它头文件到自己的项目中.我们现在可以创建测试代码了.

2. 测试实例

这里以测试cpplib_base仓库中的src/base/hash/md5.h计算md5值函数为例,展示下一个最简的单元测试如何编写.

首先我们先要创建一个test程序的main函数,我们创建了src/base/testing/test_main.cc:

#include "gtest/gtest.h"
int _tmain(int argc, char* argv[]) {
  testing::InitGoogleTest(&argc, argv);
  return RUN_ALL_TESTS();

这个main函数是必须的,作为测试程序的入口.

然后就是编写单元测试了,我们创建src/base/hash/md5_unittest.cc:

#include "base/hash/md5.h"
#include "gtest/gtest.h"
namespace base {
TEST(MD5Test, FastMD5) {
  EXPECT_EQ(FastMD5("base"), "593616de15330c0fb2d55e55410bf994");
  EXPECT_EQ(FastMD5("中国好声音"), "c567790fa04aee36bc73e42dbb5e4859");
}  // namespace base

这里使用最简单TEST来创建一个单元测试,括号内的名字官方定义是[TestCaseName,TestName],也就是测试案例的名字,测试中主要使用EXPECT*或者ASSERT*,它们的区别EXPECT执行失败,还会继续往执行,而ASSERT执行失败,就会跳过后的代码,当然只是跳过当前函数的剩余代码.

测试代码文件,有的人喜欢和源文件放一起,也有人喜欢单独放,这个都没问题,看项目组规定和个人喜好.

添加完代码后,我们需要在自己项目的CMakeLists.txt中添加(当然你可以想办法单独出去)编译单元测试程序的规则:

unittestSrc src/base/testing/test_main.cc src/base/hash/md5_unittest.cc add_executable(base_unittest ${unittestSrc}) target_link_libraries(base_unittest gtest gtest_main) target_link_libraries(base_unittest ${PROJECT_NAME}) # This is so you can do 'make test' to see all your tests run, instead of # manually running the executable runUnitTests to see those specific tests. add_test(NAME test COMMAND base_unittest)

这里因为我的主项目是一个生成一个库,而要使用它里面的函数进行测试,所以我需要测试程序链接我的主项目库.

运行单元测试

修改完CMakeLists.txt后,我们在编译时就能生成单元测试程序base_unittest,直接运行它就可以执行单元测试,或者使用make test运行ctest的方式运行单元测试:

Running main() from /home/xxx/disk2/code/cpplib_base/src/base/third_party/googletest/googletest/src/gtest_main.cc
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from MD5Test
[ RUN      ] MD5Test.FastMD5
[       OK ] MD5Test.FastMD5 (0 ms)
[----------] 1 test from MD5Test (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[  PASSED  ] 1 test.

如此,一个最简单单元测试就集成到我们的项目中了.当然这只是开始,设计好的单元测试案例远没这样简单.