欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

C++使用gtest框架編寫單元測(cè)試的教程詳解

 更新時(shí)間:2024年08月07日 09:08:52   作者:SarPro  
gtest 是 Google 開發(fā)的一個(gè)用于 C++ 的測(cè)試框架,廣泛應(yīng)用于編寫和運(yùn)行單元測(cè)試,并且支持任何類型的測(cè)試,而不僅僅是單元測(cè)試,本文本文給大家介紹了C++使用gtest框架編寫單元測(cè)試的教程,需要的朋友可以參考下

前言

gtest 是 Google 開發(fā)的一個(gè)用于 C++ 的測(cè)試框架,廣泛應(yīng)用于編寫和運(yùn)行單元測(cè)試,并且支持任何類型的測(cè)試,而不僅僅是單元測(cè)試。

注意:

  • 本教程使用 cmake 啟動(dòng)并運(yùn)行 GoogleTest:需提前安裝 CMake。
  • 術(shù)語(yǔ):測(cè)試(Test)、測(cè)試用例(Test Case)和測(cè)試套件(Test Suite)。

使用 cmake 啟動(dòng)并運(yùn)行 gtest

1. 設(shè)置項(xiàng)目

CMake 使用 CMakeLists.txt 來(lái)配置項(xiàng)目的構(gòu)建系統(tǒng)【使用該文件設(shè)置項(xiàng)目,并聲明對(duì) gtest 的依賴】

首先,創(chuàng)建一個(gè)項(xiàng)目的目錄:

mkdir my_project && cd my_project

接下來(lái),將創(chuàng)建 CMakeLists.txt 文件并聲明對(duì) GoogleTest 的依賴。

在項(xiàng)目目錄(my_project)中,創(chuàng)建一個(gè)名為 CMakeLists.txt 的文件:

vim CMakeLists.txt

其內(nèi)容如下:

cmake_minimum_required(VERSION 3.14)
project(my_project)
 
# 設(shè)置 C++ 標(biāo)準(zhǔn)為 C++14
set(CMAKE_CXX_STANDARD 14)
# 強(qiáng)制要求編譯器支持所選的 C++ 標(biāo)準(zhǔn)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
 
# 包含 FetchContent 模塊,用于從外部資源獲取依賴項(xiàng)
include(FetchContent)
FetchContent_Declare(
  googletest
  URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)
# 對(duì)于 Windows 系統(tǒng):防止覆蓋父項(xiàng)目的編譯器/鏈接器設(shè)置
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
# 使得 GoogleTest 可用
FetchContent_MakeAvailable(googletest)

這個(gè)文件中包括了以下部分:

  1. cmake_minimum_required(VERSION 3.14):指定了 CMake 的最低版本要求。
  2. project(my_project):定義了項(xiàng)目的名稱。
  3. set(CMAKE_CXX_STANDARD 14) 和 set(CMAKE_CXX_STANDARD_REQUIRED ON):設(shè)置了 C++ 標(biāo)準(zhǔn)為 C++14,且要求編譯器支持此標(biāo)準(zhǔn)。
  4. include(FetchContent):包含了 CMake 的 FetchContent 模塊,用于從外部資源(如 GitHub)獲取依賴項(xiàng)。
  5. FetchContent_Declare(googletest URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip):聲明了對(duì) GoogleTest 的依賴,指定了下載地址。
  6. set(gtest_force_shared_crt ON CACHE BOOL "" FORCE):對(duì)于 Windows 系統(tǒng),防止覆蓋父項(xiàng)目的編譯器/鏈接器設(shè)置。
  7. FetchContent_MakeAvailable(googletest):獲取并使 GoogleTest 可用。

2. 創(chuàng)建并運(yùn)行二進(jìn)制文件

將 gtest 聲明為一個(gè)依賴項(xiàng)后,你就可以在自己的項(xiàng)目中使用 GoogleTest 代碼。

舉例來(lái)說(shuō),在 my_project 目錄中創(chuàng)建一個(gè)名為 hello_test.cc 的文件:

vim hello_test.cc 

內(nèi)容如下:

#include <gtest/gtest.h>
 
// 展示一些基本斷言。
TEST(HelloTest, BasicAssertions) {
  // 期望兩個(gè)字符串不相等。
  EXPECT_STRNE("hello", "world");
  // 期望相等。
  EXPECT_EQ(7 * 6, 42);
}

要構(gòu)建代碼,需要將以下內(nèi)容添加到你的 CMakeLists.txt 文件末尾:

# 啟用測(cè)試
enable_testing()
 
# 聲明要測(cè)試的可執(zhí)行文件
add_executable(
  hello_test
  hello_test.cc
)
# 鏈接 GoogleTest 主要庫(kù)
target_link_libraries(
  hello_test
  GTest::gtest_main
)
 
# 包含 GoogleTest 模塊
include(GoogleTest)
# 使用 gtest_discover_tests 函數(shù)來(lái)自動(dòng)發(fā)現(xiàn)并添加測(cè)試
gtest_discover_tests(hello_test)

上述配置啟用了 CMake 中的測(cè)試,聲明了要構(gòu)建的 C++ 測(cè)試二進(jìn)制文件(hello_test),并將其鏈接到 GoogleTest(gtest_main)。

最后兩行啟用了 CMake 的測(cè)試運(yùn)行器,使用 GoogleTest 的 CMake 模塊來(lái)發(fā)現(xiàn)包含在二進(jìn)制文件中的測(cè)試。

現(xiàn)在你可以依據(jù)下面指令構(gòu)建和運(yùn)行你的測(cè)試:

cmake -S . -B build
  • 告訴 CMake 在當(dāng)前目錄(-S .)中查找 CMakeLists.txt 文件,并在指定的構(gòu)建目錄 build 中生成構(gòu)建系統(tǒng)文件(-B build)。
cmake --build build
  • cmake 是調(diào)用 CMake 工具的命令。
  • --build 是用于告訴 CMake 執(zhí)行構(gòu)建操作的選項(xiàng)。
  • build 是構(gòu)建目錄的路徑,指定了 CMake 在build 路徑下執(zhí)行構(gòu)建操作。
cd build && ctest
  • cd build 進(jìn)入構(gòu)建目錄。
  • ctest 會(huì)查找構(gòu)建目錄中的測(cè)試,并執(zhí)行它們。

顯示如下內(nèi)容:

恭喜!你成功地構(gòu)建并運(yùn)行了一個(gè)使用 GoogleTest 的測(cè)試二進(jìn)制文件。

gtest 入門

使用 gtest 時(shí),首先要會(huì)編寫斷言(assertions),這些是檢查條件是否為真的語(yǔ)句。

一個(gè)斷言的結(jié)果可以是成功、非致命失敗或致命失敗【如果發(fā)生致命失敗,它會(huì)中止當(dāng)前函數(shù);否則程序會(huì)正常繼續(xù)執(zhí)行】

測(cè)試使用斷言來(lái)驗(yàn)證被測(cè)試代碼的行為。如果一個(gè)測(cè)試崩潰或有一個(gè)失敗的斷言,那么它失敗;否則它成功。

  • 一個(gè)測(cè)試套件(test suite)包含一個(gè)或多個(gè)測(cè)試(test)。應(yīng)該將你的測(cè)試(test)分組到反映被測(cè)代碼結(jié)構(gòu)的測(cè)試套件(test suite)中。
  • 一個(gè)測(cè)試程序可以包含多個(gè)測(cè)試套件(test suite)。

接下來(lái),我們將解釋如何編寫一個(gè)測(cè)試程序,從單個(gè)斷言級(jí)別開始,逐步構(gòu)建到測(cè)試和測(cè)試套件。

1 斷言(assertions)

斷言(assertions)是類似函數(shù)調(diào)用的宏。你可以通過(guò)對(duì)其行為進(jìn)行斷言來(lái)測(cè)試一個(gè)類或函數(shù)。當(dāng)一個(gè)斷言失敗時(shí),gtest 會(huì)打印斷言的源文件和行號(hào)位置,以及一個(gè)失敗消息。你還可以提供一個(gè)自定義的失敗消息,它將附加到 gtest 的消息中。

這些斷言成對(duì)出現(xiàn),測(cè)試相同的事物,但對(duì)當(dāng)前函數(shù)有不同的影響。

  • ASSERT_* 版本在失敗時(shí)會(huì)生成致命失敗,并中止當(dāng)前函數(shù)。
  • EXPECT_* 版本生成非致命失敗,不會(huì)中止當(dāng)前函數(shù)。

通常情況下,優(yōu)先使用 EXPECT_*,因?yàn)樗鼈冊(cè)试S在一個(gè)測(cè)試中報(bào)告多個(gè)失敗。然而,如果在相關(guān)斷言失敗時(shí)繼續(xù)執(zhí)行不合理,則應(yīng)該使用 ASSERT_*。

由于失敗的 ASSERT_* 會(huì)立即返回當(dāng)前函數(shù),可能會(huì)跳過(guò)其后的清理代碼,從而可能導(dǎo)致空間泄漏。根據(jù)泄漏的性質(zhì),如果除了斷言錯(cuò)誤外還出現(xiàn)堆檢查器錯(cuò)誤。

要提供自定義的失敗消息,只需使用 << 運(yùn)算符或一系列此類運(yùn)算符將其流式傳遞到宏中。

【示例】使用 ASSERT_EQ 和 EXPECT_EQ 宏來(lái)驗(yàn)證值的相等性:

ASSERT_EQ(x.size(), y.size()) << "Vectors x and y are of unequal length";
 
for (int i = 0; i < x.size(); ++i) {
  EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i;
}

任何可以流式傳輸?shù)?ostream 的內(nèi)容都可以流式傳輸?shù)綌嘌院曛?- 特別是 C 字符串和字符串對(duì)象。如果將寬字符串(wchar_t*、 TCHAR*在 Windows 的UNICODE 模式下,或者 std::wstring)流式傳輸?shù)綌嘌灾?,則在打印時(shí)會(huì)被轉(zhuǎn)換為 UTF-8 編碼。

gtest 提供了一系列斷言,用于以各種方式驗(yàn)證代碼的行為??梢詸z查布爾條件,基于關(guān)系運(yùn)算符比較值,驗(yàn)證字符串值、浮點(diǎn)值等等。甚至還有一些斷言可以通過(guò)提供自定義謂詞來(lái)驗(yàn)證更復(fù)雜的狀態(tài)。

2 簡(jiǎn)單測(cè)試

  • 使用 TEST() 宏來(lái)定義和命名一個(gè)測(cè)試函數(shù)。這些是普通的 C++ 函數(shù),不返回任何值。
  • 在這個(gè)函數(shù)中,除了你想包含的有效的 C++ 語(yǔ)句,使用各種 gtest 斷言來(lái)檢查值。
  • 測(cè)試結(jié)果由斷言確定;如果測(cè)試中的任何斷言失?。o(wú)論是致命還是非致命),或者測(cè)試崩潰,整個(gè)測(cè)試都將失敗。否則,它成功。
TEST(TestSuiteName, TestName) {
  ... test body ...
}

TEST() 宏的第一個(gè)參數(shù)是測(cè)試套件(test suite)的名稱,第二個(gè)參數(shù)是測(cè)試套件內(nèi)的測(cè)試名稱。兩個(gè)名稱都必須是有效的 C++ 標(biāo)識(shí)符,并且不能包含下劃線【測(cè)試的全名=其所屬的測(cè)試套件+其單獨(dú)的名稱組成。來(lái)自不同測(cè)試套件的測(cè)試可以有相同的單獨(dú)名稱】

【示例】以一個(gè)簡(jiǎn)單的整數(shù)函數(shù)為例

int Factorial(int n);  // 返回 n 的階乘

此函數(shù)的測(cè)試套件可能如下:

// 測(cè)試 0 的階乘
TEST(FactorialTest, HandlesZeroInput) {
  // 期望 Factorial(0) 的結(jié)果是 1
  EXPECT_EQ(Factorial(0), 1);
}
 
// 測(cè)試正數(shù)的階乘
TEST(FactorialTest, HandlesPositiveInput) {
  // 期望 Factorial(1) 的結(jié)果是 1
  EXPECT_EQ(Factorial(1), 1);
  // 期望 Factorial(2) 的結(jié)果是 2
  EXPECT_EQ(Factorial(2), 2);
  // 期望 Factorial(3) 的結(jié)果是 6
  EXPECT_EQ(Factorial(3), 6);
  // 期望 Factorial(8) 的結(jié)果是 40320
  EXPECT_EQ(Factorial(8), 40320);
}

GoogleTest 按測(cè)試套件分組測(cè)試結(jié)果,因此邏輯上相關(guān)的測(cè)試應(yīng)在同一個(gè)測(cè)試套件中;換句話說(shuō),它們的 TEST() 的第一個(gè)參數(shù)應(yīng)該相同。

在上面的示例中,我們有兩個(gè)測(cè)試,HandlesZeroInput 和 HandlesPositiveInput,它們屬于同一個(gè)測(cè)試套件 FactorialTest。

在命名你的測(cè)試套件和測(cè)試時(shí),應(yīng)該遵循與命名函數(shù)和類相同的約定。

3 測(cè)試夾具:為多個(gè)測(cè)試使用相同的數(shù)據(jù)配置

Test Fixture(測(cè)試夾具)是指在測(cè)試運(yùn)行前后,需要被執(zhí)行的代碼片段。

如果你發(fā)現(xiàn)自己在編寫兩個(gè)或更多操作相似數(shù)據(jù)的測(cè)試,可以使用測(cè)試夾具。這樣可以為多個(gè)不同的測(cè)試重復(fù)使用相同的對(duì)象配置。

創(chuàng)建夾具的步驟:

  1. 從 testing::Test 派生一個(gè)類。在類體開始處使用 protected:,因?yàn)槲覀兿M麖淖宇愒L問(wèn)夾具成員。
  2. 在類中聲明你需要使用的任何對(duì)象。
  3. 如果需要,編寫一個(gè)默認(rèn)構(gòu)造函數(shù)或 SetUp() 函數(shù),為每個(gè)測(cè)試準(zhǔn)備對(duì)象。
    一個(gè)常見(jiàn)的錯(cuò)誤是將 SetUp() 拼寫為小寫的 Setup() - 在 C++11 中使用 override 確保拼寫正確。
  4. 如果需要,編寫一個(gè)析構(gòu)函數(shù)或 TearDown() 函數(shù)來(lái)釋放你在 SetUp() 中分配的任何資源。
  5. 如果需要,為你的測(cè)試定義共享的子程序。
// 定義夾具類
class MyTestFixture : public testing::Test {
protected:
    // 在這里聲明你的對(duì)象
    int* myObject;
 
    // 如果需要,編寫構(gòu)造函數(shù)或 SetUp() 函數(shù)
    void SetUp() override {
        myObject = new int(42); // 示例初始化
    }
 
    // 如果需要,編寫析構(gòu)函數(shù)或 TearDown() 函數(shù)
    void TearDown() override {
        delete myObject;
    }
};
 
// 使用 TEST_F() 進(jìn)行測(cè)試
TEST_F(MyTestFixture, Test1) {
    // 可以在這里訪問(wèn) myObject
    EXPECT_EQ(*myObject, 42);
}
 
TEST_F(MyTestFixture, Test2) {
    // 也可以在這里訪問(wèn) myObject
    EXPECT_NE(*myObject, 0);
}

使用夾具時(shí),使用 TEST_F() 而不是 TEST(),因?yàn)樗试S你訪問(wèn)測(cè)試夾具中的對(duì)象和子程序:

TEST_F(TestFixtureClassName, TestName) {
  ... test body ...
}

到此這篇關(guān)于C++使用gtest框架編寫單元測(cè)試的教程詳解的文章就介紹到這了,更多相關(guān)C++ gtest單元測(cè)試內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 淺談Qt信號(hào)槽與事件循環(huán)的關(guān)系

    淺談Qt信號(hào)槽與事件循環(huán)的關(guān)系

    本文主要介紹了Qt信號(hào)槽與事件循環(huán)的關(guān)系,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • 一個(gè)快速排序算法代碼分享

    一個(gè)快速排序算法代碼分享

    一個(gè)快速排序算法代碼一個(gè)快速排序算法代碼,代碼內(nèi)有注釋,大家參考使用吧
    2014-01-01
  • 一篇文章徹底弄懂C++虛函數(shù)的實(shí)現(xiàn)機(jī)制

    一篇文章徹底弄懂C++虛函數(shù)的實(shí)現(xiàn)機(jī)制

    C++中的虛函數(shù)的作用主要是實(shí)現(xiàn)了多態(tài)的機(jī)制,基類定義虛函數(shù),子類可以重寫該函數(shù),在派生類中對(duì)基類定義的虛函數(shù)進(jìn)行重寫時(shí),需要在派生類中聲明該方法為虛方法,這篇文章主要給大家介紹了關(guān)于如何通過(guò)一篇文章徹底弄懂C++虛函數(shù)的實(shí)現(xiàn)機(jī)制,需要的朋友可以參考下
    2021-06-06
  • 基于C語(yǔ)言實(shí)現(xiàn)的迷宮算法示例

    基于C語(yǔ)言實(shí)現(xiàn)的迷宮算法示例

    這篇文章主要介紹了基于C語(yǔ)言實(shí)現(xiàn)的迷宮算法,結(jié)合具體實(shí)例形式分析了C語(yǔ)言解決迷宮問(wèn)題算法的實(shí)現(xiàn)技巧與相關(guān)注意事項(xiàng),需要的朋友可以參考下
    2017-09-09
  • OpenCV實(shí)現(xiàn)圖像去噪算法的步驟詳解

    OpenCV實(shí)現(xiàn)圖像去噪算法的步驟詳解

    這篇文章主要為大家介紹了OpenCV中圖像去噪算法的原理,文中通過(guò)示例為大家詳細(xì)講解了圖像去噪算法的使用,感興趣的小伙伴可以了解一下
    2022-06-06
  • 關(guān)于C語(yǔ)言strlen與sizeof區(qū)別詳情

    關(guān)于C語(yǔ)言strlen與sizeof區(qū)別詳情

    對(duì)于 strlen 和 sizeof,相信不少程序員會(huì)混淆其功能。雖然從表面上看它們都可以求字符串的長(zhǎng)度,但二者卻存在著許多不同之處及本質(zhì)區(qū)別,今天得這篇文章我們就來(lái)學(xué)習(xí)C語(yǔ)言strlen與sizeof區(qū)別的相關(guān)資料,需要的朋友可以參考一下
    2021-10-10
  • C語(yǔ)言從編譯到運(yùn)行過(guò)程詳解

    C語(yǔ)言從編譯到運(yùn)行過(guò)程詳解

    這篇文章主要介紹了C語(yǔ)言從編譯到運(yùn)行的一個(gè)過(guò)程的相關(guān)資料,需要的朋友可以參考下面文章具體的內(nèi)容
    2021-09-09
  • C++ 中的 if-constexpr語(yǔ)法和作用

    C++ 中的 if-constexpr語(yǔ)法和作用

    ?if-constexpr語(yǔ)法是 C++ 17 引入的新語(yǔ)法特性,也被稱為常量 if 表達(dá)式或靜態(tài) if(static if),這篇文章主要介紹了C++ 中的 if-constexpr語(yǔ)法和作用,需要的朋友可以參考下
    2025-03-03
  • C語(yǔ)言實(shí)現(xiàn)的統(tǒng)計(jì)php代碼行數(shù)功能源碼(支持文件夾、多目錄)

    C語(yǔ)言實(shí)現(xiàn)的統(tǒng)計(jì)php代碼行數(shù)功能源碼(支持文件夾、多目錄)

    這篇文章主要介紹了C語(yǔ)言實(shí)現(xiàn)的統(tǒng)計(jì)php代碼行數(shù)功能源碼,支持文件夾、多級(jí)目錄的統(tǒng)計(jì),在一些環(huán)境中會(huì)用到這個(gè)功能,需要的朋友可以參考下
    2014-08-08
  • 深度揭秘C++面向?qū)ο缶幊讨欣^承的核心概念

    深度揭秘C++面向?qū)ο缶幊讨欣^承的核心概念

    我們知道C語(yǔ)言是面向過(guò)程的編程語(yǔ)言,C++在C語(yǔ)言的基礎(chǔ)上進(jìn)化出了面向?qū)ο蟮哪P停^承就是面向?qū)ο蟮闹匾獙傩?,下面就讓小編?lái)和大家詳細(xì)講講吧
    2023-07-07

最新評(píng)論