本篇 ShengYu 介紹 GoogleTest 用法與教學,Google test 又稱為 gtest,gtest 是一個 C++ 的單元測試框架(unit testing framework),gtest 是由 Google 所開發出來的,
以下 Google Test 內容將分為這幾部份,
- 下載編譯安裝
- googletest 常用語法
- googletest 基本的 C++ 單元測試
- 查詢 googletest 的版本
- 有在使用 googletest 的開源專案
- 其它有 test 的開源專案
下載編譯安裝
以下是 GoogleTest 的下載與編譯步驟,1
2
3
4
5
6$ git clone https://github.com/google/googletest
$ cd googletest
$ mkdir build
$ cd build
$ cmake -DCMAKE_CXX_FLAGS=-std=c++11 -Dgtest_build_samples=ON ..
$ make -j4
googletest 原始碼目錄下有 googletest 與 googlemock,
注意要切換到 googletest/ 頂層目錄去編譯,不是切換到 googletest/googletest/ 下編譯,否則你可能會遇到 cmake 的錯誤,1
2
3
4
5
6
7
8
9CMake Error at CMakeLists.txt:129 (set_target_properties):
set_target_properties called with incorrect number of arguments.
CMake Error at CMakeLists.txt:131 (set_target_properties):
set_target_properties called with incorrect number of arguments.
-- Configuring incomplete, errors occurred!
在 Ubuntu 16.04 下可能會遇到編譯錯誤的訊息,需要加上 std=c++11
的編譯選項,一種方法是在 CMakeLists.txt 裡加入 set(CMAKE_CXX_STANDARD 11)
或 -DCMAKE_CXX_FLAGS=-std=c++11
另外如果電腦是多核心可以下 make -j4
有助於提升編譯速度,
如果要安裝到系統的話,請輸入下列指令,1
sudo make install
你可以在 /usr/local/include/ 目錄下發現有新的 gtest/gtest.h 標頭檔/usr/local/include/gtest/gtest.h
你也可以在 /usr/local/lib/ 目錄下發現有新的 libgtest 靜態函式庫/usr/local/lib/libgtest.a
這些待會都會用到,
googletest 常用語法
這邊列出幾個 googletest 常用斷言,googletest 中定義的斷言如下,
基本斷言
判斷 condition 為真ASSERT_TRUE(condition);
EXPECT_TRUE(condition);
判斷 condition 為假ASSERT_FALSE(condition);
EXPECT_FALSE(condition);
數字比較
語法為 ASSERT_EQ(期待值,實際值)
,期待值和實際值不等時,測試失敗
判斷兩數是否相等,expected == actualASSERT_EQ(expected,actual);
EXPECT_EQ(expected,actual);
判斷兩數是否不相等,val1 != val2ASSERT_NE(val1,val2);
EXPECT_NE(val1,val2);
判斷 val1 是否小於 val2,val1 < val2ASSERT_LT(val1,val2);
EXPECT_LT(val1,val2);
判斷 val1 是否小於等於 val2,val1 <= val2ASSERT_LE(val1,val2);
EXPECT_LE(val1,val2);
判斷 val1 是否大於 val2,val1 > val2ASSERT_GT(val1,val2);
EXPECT_GT(val1,val2);
判斷 val1 是否大於等於 val2,val1 >= val2ASSERT_GE(val1,val2);
EXPECT_GE(val1,val2);
字元字串比較
判斷兩個 C-style 字元字串有相同的內容ASSERT_STREQ(expected_str,actual_str);
EXPECT_STREQ(expected_str,actual_str);
判斷兩個 C-style 字元字串有不同的內容ASSERT_STRNE(str1,str2);
EXPECT_STRNE(str1,str2);
判斷兩個 C-style 字元字串有相同的內容,忽略大小寫ASSERT_STRCASEEQ(expected_str,actual_str);
EXPECT_STRCASEEQ(expected_str,actual_str);
判斷兩個 C-style 字元字串有不同的內容,忽略大小寫ASSERT_STRCASENE(str1,str2);
EXPECT_STRCASENE(str1,str2);
googletest 基本的 C++ 單元測試
這邊就示範一下怎麼用 GoogleTest 來寫單元測試,假如我要測試我寫的 myadd 函式的話,1
2
3
4
5
6
7
8
9
10
11
12
13
14
int myadd(int a, int b) {
return a + b;
}
TEST(testCase, test1) {
EXPECT_EQ(myadd(2, 3), 5);
}
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
接下來用 cmake 編譯或 g++ 編譯都可以,我這邊簡單的用 g++ 作示範,1
g++ gtest-add.cpp -o a.out -std=c++11 -lgtest -lpthread
或者使用 pkg-config 來輔助,1
g++ gtest-add.cpp -o a.out -std=c++11 `pkg-config --libs gtest`
執行 a.out 後就可以看到測試的輸出囉~1
2
3
4
5
6
7
8
9
10
11$ ./a.out
[==========] Running 1 test from 1 test suite.
[----------] Global test environment set-up.
[----------] 1 test from testCase
[ RUN ] testCase.test1
[ OK ] testCase.test1 (0 ms)
[----------] 1 test from testCase (0 ms total)
[----------] Global test environment tear-down
[==========] 1 test from 1 test suite ran. (0 ms total)
[ PASSED ] 1 test.
多加幾個測試項目,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
37
38
39// g++ gtest-arithmetic.cpp -o a.out -std=c++11 -lgtest -lpthread
int myadd(int a, int b) {
return a + b;
}
int mysub(int a, int b) {
return a - b;
}
int mymul(int a, int b) {
return a * b;
}
int mydiv(int a, int b) {
return a / b;
}
TEST(testCase, test1) {
EXPECT_EQ(myadd(2, 3), 5);
}
TEST(testCase, test2) {
EXPECT_EQ(mysub(2, 3), -1);
}
TEST(testCase, test3) {
EXPECT_EQ(mymul(3, 4), 12);
}
TEST(testCase, test4) {
EXPECT_EQ(mydiv(21, 7), 3);
}
int main(int argc, char **argv) {
testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
輸出結果如下,1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17$ ./a.out
[==========] Running 4 tests from 1 test suite.
[----------] Global test environment set-up.
[----------] 4 tests from testCase
[ RUN ] testCase.test1
[ OK ] testCase.test1 (0 ms)
[ RUN ] testCase.test2
[ OK ] testCase.test2 (0 ms)
[ RUN ] testCase.test3
[ OK ] testCase.test3 (0 ms)
[ RUN ] testCase.test4
[ OK ] testCase.test4 (0 ms)
[----------] 4 tests from testCase (0 ms total)
[----------] Global test environment tear-down
[==========] 4 tests from 1 test suite ran. (0 ms total)
[ PASSED ] 4 tests.
另外如果 link 連結 gtest_main 的話,就會幫你連結一個 main 主程式入口,那麼你就可以省略不用寫 main 主函式了,1
g++ gtest-add.cpp -o a.out -std=c++11 -lgtest -lgtest_main -lpthread
那麼程式碼就可以改成這樣,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// g++ gtest-arithmetic2.cpp -o a.out -std=c++11 -lgtest -lgtest_main -lpthread
int myadd(int a, int b) {
return a + b;
}
int mysub(int a, int b) {
return a - b;
}
int mymul(int a, int b) {
return a * b;
}
int mydiv(int a, int b) {
return a / b;
}
TEST(testCase, test1) {
EXPECT_EQ(myadd(2, 3), 5);
}
TEST(testCase, test2) {
EXPECT_EQ(mysub(2, 3), -1);
}
TEST(testCase, test3) {
EXPECT_EQ(mymul(3, 4), 12);
}
TEST(testCase, test4) {
EXPECT_EQ(mydiv(21, 7), 3);
}
如果是選用 cmake 編譯系統的話 CMakeLists.txt 可以這樣寫,1
2
3
4
5
6
7
8
9
10
11
12cmake_minimum_required(VERSION 3.0)
project(gtest-example)
#set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
add_executable(gtest-arithmetic gtest-arithmetic2.cpp)
target_link_libraries(gtest-arithmetic PRIVATE gtest gtest_main pthread)
#set_property(TARGET gtest-arithmetic PROPERTY CXX_STANDARD 11)
enable_testing()
add_test(test_arithmetic1 gtest-arithmetic)
查詢 googletest 的版本
googletest 版本號碼在 CMakeLists.txt 裡會去設定的 GOOGLETEST_VERSION 變數,1
set(GOOGLETEST_VERSION 1.10.0)
有在使用 googletest 的開源專案
這邊列出比較知名的大型開源專案有在用 googletest,你可以參考學習他們的測試程式碼如何撰寫,有在使用 googletest 的知名開源專案如下,
OpenCV
測試範例:
test_pyramid.cpp
test_grabcut.cpp
test_jpeg.cpp
Kodi(舊名xbmc)
測試範例:
TestNetwork.cpp
TestWebServer.cpp
TestCPUInfo.cpp
Testlog.cpp
gRPC
測試範例:
cmdline_test.cc
stack_tracer_test.cc
mock_stream_test.cc
glog
測試範例:
stl_logging_unittest.cc
logging_unittest.cc
其它有 test 的開源專案
以下是其它有 test 的開源專案,也可以參考看看,
bitcoin
使用 boost test,測試範例:
base64_tests.cpp
crypto_tests.cpp
logging_tests.cpp
sock_tests.cpp
spdlog
使用 Catch2,測試範例:
test_backtrace.cpp
test_misc.cpp
其他參考
C++ 单元测试框架-gtest | Mike’s Blog
https://mikeblog.top/2019/01/02/googletest/
快速上手Google C++ 測試框架googletest_記錄學習的過程-CSDN博客
https://blog.csdn.net/weiwei9363/article/details/103469525
c++单元测试之gtest测试框架快速上手_guotianqing的博客-CSDN博客
https://blog.csdn.net/guotianqing/article/details/104055221
C Unit Test Framework 介紹 (Googletest) | by 亮谷 | Medium
https://medium.com/@ktvexe/c-unit-test-framework-%E4%BB%8B%E7%B4%B9-googletest-9713dadceb7a
輕鬆編寫 C++ 單元測試 | 開源互助社區
https://coctec.com/docs/linux/show-post-68880.html
其它相關文章推薦
C/C++ 新手入門教學懶人包
C/C++ 字串轉數字的4種方法
C++ virtual 的兩種用法
C/C++ 字串反轉 reverse
C/C++ call by value傳值, call by pointer傳址, call by reference傳參考 的差別
C++ 類別樣板 class template
std::sort 用法與範例
std::find 用法與範例
std::queue 用法與範例
std::map 用法與範例
std::deque 用法與範例
std::vector 用法與範例