这里以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来创建一个单元测试,主要使用EXPECT*
或者ASSERT*
,它们的区别EXPECT
执行失败,还会继续往执行,而ASSERT
执行失败,就会跳过后的代码,当然只是跳过当前测试单元的剩余代码.
测试代码文件,有的人喜欢和源文件放一起,也有人喜欢单独放,这个都没问题,看项目组规定和个人喜好.
添加完代码后,我们需要在自己项目的CMakeLists.txt
中添加(当然你可以想办法单独出去)编译单元测试程序的规则:
set(
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.
如此,一个最简单单元测试就集成到我们的项目中了.当然这只是开始,设计好的单元测试案例远没这样简单.