本篇 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 9 CMake 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
有助於提升編譯速度,
如果要安裝到系統的話,請輸入下列指令,
你可以在 /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 函式的話,gtest-add.cpp 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #include <gtest/gtest.h> 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.
多加幾個測試項目,gtest-arithmetic.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 37 38 39 #include <gtest/gtest.h> 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
那麼程式碼就可以改成這樣,gtest-arithmetic2.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 #include <gtest/gtest.h> 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 可以這樣寫,CMakeLists.txt 1 2 3 4 5 6 7 8 9 10 11 12 cmake_minimum_required (VERSION 3.0 )project (gtest-example)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)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 Bloghttps://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 亮谷 | Mediumhttps://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 用法與範例