這里以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
中添加(當然你可以想辦法單獨出去)編譯單元測試程序的規則:
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.
如此,一個最簡單單元測試就集成到我們的項目中了.當然這只是開始,設計好的單元測試案例遠沒這樣簡單.