一、C++中的斷言機(jī)制
??這部分內(nèi)容網(wǎng)上已經(jīng)有很多人講了,我就不做重復(fù)性工作,制造垃圾了,大家看看下面兩個(gè)鏈接就可以了,因?yàn)槲业膶诔朔窒碜约簩W(xué)習(xí)的知識(shí),主要想為大家提供完整學(xué)習(xí)路線,讓大家的知識(shí)體系更加完善!
1、傳統(tǒng)的運(yùn)行時(shí)斷言
(1)參考:https://www.cnblogs.com/lvchaoshun/p/7816288.html
2、C++11編譯時(shí)斷言
(1)參考:https://winsoft666.blog.csdn.net/article/details/78521458
(2)更深層:https://blog.csdn.net/weixin_39956356/article/details/111482530
二、單元測(cè)試和gtest介紹
1、單元測(cè)試介紹
(1)測(cè)試是對(duì)軟件的功能、可靠性、兼容性等要求所做的檢驗(yàn)
(2)測(cè)試有多種分類和概念,譬如白盒和黑盒,自動(dòng)化測(cè)試等
白盒測(cè)試又稱結(jié)構(gòu)測(cè)試、透明盒測(cè)試、邏輯驅(qū)動(dòng)測(cè)試或基于代碼的測(cè)試。白盒測(cè)試是
一種測(cè)試用例設(shè)計(jì)方法,盒子指的是被測(cè)試的軟件,白盒指的是盒子是可視的,即清楚盒
子內(nèi)部的東西以及里面是如何運(yùn)作的。
"白盒"法全面了解程序內(nèi)部邏輯結(jié)構(gòu)、對(duì)所有邏輯路徑進(jìn)行測(cè)試。"白盒"法是窮舉
路徑測(cè)試。在使用這一方案時(shí),測(cè)試者必須檢查程序的內(nèi)部結(jié)構(gòu),從檢查程序的邏輯著手,
得出測(cè)試數(shù)據(jù)。貫穿程序的獨(dú)立路徑數(shù)是天文數(shù)字。
原則:
(1)一個(gè)模塊中的所有獨(dú)立路徑至少被測(cè)試一次。
(2)所有邏輯值均需測(cè)試true和false兩種情況。
(3)檢査程序的內(nèi)部數(shù)據(jù)結(jié)構(gòu),保證其結(jié)構(gòu)的有效性。
(4)在取值的上、下邊界及可操作范圍內(nèi)運(yùn)行所有循環(huán)。
黑盒測(cè)試,它是通過(guò)測(cè)試來(lái)檢測(cè)每個(gè)功能是否都能正常使用。在測(cè)試中,把程序看作
一個(gè)不能打開(kāi)的黑盒子,在完全不考慮程序內(nèi)部結(jié)構(gòu)和內(nèi)部特性的情況下,在程序接口進(jìn)
行測(cè)試,它只檢查程序功能是否按照需求規(guī)格說(shuō)明書(shū)的規(guī)定正常使用,程序是否能適當(dāng)?shù)?接收輸入數(shù)據(jù)而產(chǎn)生正確的輸出信息。黑盒測(cè)試著眼于程序外部結(jié)構(gòu),不考慮內(nèi)部邏輯結(jié)
構(gòu),主要針對(duì)軟件界面和軟件功能進(jìn)行測(cè)試。
黑盒測(cè)試是以用戶的角度,從輸入數(shù)據(jù)與輸出數(shù)據(jù)的對(duì)應(yīng)關(guān)系出發(fā)進(jìn)行測(cè)試的。很明
顯,如果外部特性本身設(shè)計(jì)有問(wèn)題或規(guī)格說(shuō)明的規(guī)定有誤,用黑盒測(cè)試方法是發(fā)現(xiàn)不了的。
黑盒測(cè)試又叫功能測(cè)試、數(shù)據(jù)驅(qū)動(dòng)測(cè)試或基于需求規(guī)格說(shuō)明書(shū)的功能測(cè)試。該類測(cè)試
注重于測(cè)試軟件的功能性需求。
在軟件測(cè)試的各個(gè)階段,如單元測(cè)試、集成測(cè)試、系統(tǒng)測(cè)試及驗(yàn)收測(cè)試等階段中,黑
盒測(cè)試都發(fā)揮著重要作用,尤其在系統(tǒng)測(cè)試和確認(rèn)測(cè)試中,其作用是其他測(cè)試方法無(wú)法取
代的。
自動(dòng)化測(cè)試一般是指軟件測(cè)試的自動(dòng)化,軟件測(cè)試就是在預(yù)設(shè)條件下運(yùn)行系統(tǒng)或應(yīng)用
程序,評(píng)估運(yùn)行結(jié)果,預(yù)先條件應(yīng)包括正常條件和異常條件。
自動(dòng)化測(cè)試是把以人為驅(qū)動(dòng)的測(cè)試行為轉(zhuǎn)化為機(jī)器執(zhí)行的一種過(guò)程。通常,在設(shè)計(jì)了
測(cè)試用例并通過(guò)評(píng)審之后,由測(cè)試人員根據(jù)測(cè)試用例中描述的規(guī)程一步步執(zhí)行測(cè)試,得到
實(shí)際結(jié)果與期望結(jié)果的比較。在此過(guò)程中,為了節(jié)省人力、時(shí)間或硬件資源,提高測(cè)試效
率,便引入了自動(dòng)化測(cè)試的概念。
有自動(dòng)化測(cè)試軟件工具進(jìn)行測(cè)試,也可編寫腳本進(jìn)行測(cè)試
(3)測(cè)試是一種獨(dú)立的學(xué)問(wèn),在軟件行業(yè)中和開(kāi)發(fā)是并列的,我們并不深究
(4)單元測(cè)試,unittest,是模塊開(kāi)發(fā)者自己編寫的測(cè)試模塊的用例,目的是保證模塊符合開(kāi)發(fā)要求,可以與其他開(kāi)發(fā)人員的開(kāi)發(fā)的模塊可以協(xié)同工作
(5)測(cè)試驅(qū)動(dòng)開(kāi)發(fā)(開(kāi)發(fā)方法)
??測(cè)試驅(qū)動(dòng)開(kāi)發(fā),英文全稱Test-Driven Development,簡(jiǎn)稱TDD,是一種不同于傳統(tǒng)軟件開(kāi)發(fā)流程的新型的開(kāi)發(fā)方法。它要求在編寫某個(gè)功能的代碼之前先編寫測(cè)試代碼,然后只編寫使測(cè)試通過(guò)的功能代碼,通過(guò)測(cè)試來(lái)推動(dòng)整個(gè)開(kāi)發(fā)的進(jìn)行。這有助于編寫簡(jiǎn)潔可用和高質(zhì)量的代碼,并加速開(kāi)發(fā)過(guò)程。
??如今,一些公司將自己的一些業(yè)務(wù)外包給第三方公司就使用了這種思想,自己提供測(cè)試用例以及測(cè)試標(biāo)準(zhǔn),讓第三方公司去開(kāi)發(fā)軟件,如果不符合自己的測(cè)試程序就去修改,直至第三方開(kāi)發(fā)出符合自己測(cè)試程序以及測(cè)試標(biāo)準(zhǔn)的軟件才算達(dá)到自己的要求!
2、常見(jiàn)單元測(cè)試介紹(測(cè)試框架)
(1)Java的Junit
(2)C++的CppUnit和CxxUnit
(3).net的Nunit
.NET是一種用于構(gòu)建多種應(yīng)用的免費(fèi)開(kāi)源開(kāi)發(fā)平臺(tái),可以使用多種語(yǔ)言,編輯器和庫(kù)
開(kāi)發(fā)Web應(yīng)用、Web API和微服務(wù)、云中的無(wú)服務(wù)器函數(shù)、云原生應(yīng)用、移動(dòng)應(yīng)用、桌面應(yīng)
用、Windows WPF、Windows窗體、通用 Windows平臺(tái) (UWP)、游戲、物聯(lián)網(wǎng) (IoT)、
機(jī)器學(xué)習(xí)、控制臺(tái)應(yīng)用、Windows服務(wù)。.NET類庫(kù)在不同應(yīng)用和應(yīng)用類型中共享功能,無(wú)
論構(gòu)建哪種類型的應(yīng)用,代碼和項(xiàng)目文件看起來(lái)都一樣,可以訪問(wèn)每個(gè)應(yīng)用的相同運(yùn)行時(shí)、
API和語(yǔ)言功能。
2022年6月,微軟承認(rèn) Visual Studio、NET 在 Win11 上存在問(wèn)題,正努力修復(fù)。
(4)google 的 gtest(目前C++開(kāi)發(fā)常用的)和 gmock(gtest的升級(jí)版,用于有依賴的模塊進(jìn)行單元測(cè)試,該模塊依賴于其他模塊方可工作)
3、gtest介紹
(1)gtest是google開(kāi)發(fā)和開(kāi)源的單元測(cè)試套件,是C++單元測(cè)試的最佳選擇
(2)gtest主頁(yè):https://github.com/google/googletest
(3)gtest大多情況下已經(jīng)夠用,gmock額外提供了有依賴情況下的單元測(cè)試能力,需要時(shí)再去學(xué)習(xí)了解其的使用。
三、gtest的安裝和使用
1、ubuntu 20.04 安裝 gtest v1.10.0版本
(1)參考:https://www.cnblogs.com/Jessica-jie/p/6704388.html
test:gtest自己的一些測(cè)試文件
samples:提供的一些示例代碼
CMakeLists.txt:管理gtest項(xiàng)目的cmake工程文件
(2)需要camke,可能還有其他依賴,按需安裝
$ sudo apt-get install cmake
2、sample編譯
(1)全編譯,按readme操作。編譯完運(yùn)行測(cè)試體驗(yàn)。
https://github.com/google/googletest/blob/main/googletest/README.md
.cc:C++源代碼文件
sample1.cc、sample1.h:待測(cè)試的功能文件
sample1_unittest.cc:進(jìn)行單元測(cè)試的文件
編譯命令:
摘錄自V1.10.0版本的gtest中的README.md文件(googletest\googletest\README.md)
#### Standalone CMake Project
When building Google Test as a standalone project, the typical workflow
starts with:
mkdir mybuild # Create a directory to hold the build output.
cd mybuild
cmake ${GTEST_DIR} # Generate native build scripts.
If you want to build Google Test's samples, you should replace the last
command with
cmake -Dgtest_build_samples=ON ${GTEST_DIR}
#########################################################################
cmake -Dgtest_build_samples=ON .. # ".." 表示我的CMakeLists.txt所在的目錄
(2)手工編譯,sample2編譯(操作步驟如下圖所示):
將下面的命令放到一個(gè)Makefile文件中,可使用make一鍵編譯程序,具體步驟如上圖所示:
sudo g++ sample2_unittest.cc sample2.cc -o sample2 -lgtest_main -lgtest -lpthread
四、gtest 的 sample1 解讀
(1)編譯文件命令:
sudo g++ sample1_unittest.cc sample1.cc -o sample1 -lgtest_main -lgtest -lpthread
(2)執(zhí)行編譯得到的sample1 ,看看執(zhí)行效果
(3)使用SourceInsight或者VScode軟件分析源碼,sample1是一個(gè)用來(lái)測(cè)試函數(shù)功能的
示例
//sample1.cc 需要被測(cè)試的功能
//演示使用Google C++測(cè)試框架的示例程序。
#include "sample1.h"
// 返回n?。╪的階乘)。對(duì)于n小于0,n!定義為1。
int Factorial(int n) {
int result = 1;
for (int i = 1; i <= n; i++) {
result *= i;
}
return result;
}
// 當(dāng)且僅當(dāng)n是素?cái)?shù)時(shí)返回true
//“素?cái)?shù)一般指質(zhì)數(shù)。質(zhì)數(shù)是指在大于1的自然數(shù)中,
//除了1和它本身以外不再有其他因數(shù)的自然數(shù)。
bool IsPrime(int n) {
// Trivial case 1: small numbers
if (n <= 1) return false;
// Trivial case 2: even numbers
if (n % 2 == 0) return n == 2;
// Now, we have that n is odd and n >= 3.
// Try to divide n by every odd number i, starting from 3
for (int i = 3; ; i += 2) {
//我們只需要把i試到n的平方根
if (i > n/i) break;
// Now, we have i <= n/i < n.
// If n is divisible by i, n is not prime.
if (n % i == 0) return false;
}
// n在范圍(1,n)內(nèi)沒(méi)有整數(shù)因子,因此是素?cái)?shù)。
return true;
}
//sample1_unittest.cc 具有測(cè)試功能的代碼
//演示使用Google C++測(cè)試框架的示例程序。
//此示例演示如何為函數(shù)編寫簡(jiǎn)單的單元測(cè)試,
//使用Google C++測(cè)試框架編寫單元測(cè)試很簡(jiǎn)單,如1-2-3所示:
//步驟1.包括必要的頭文件
//聲明測(cè)試邏輯需求。
//別忘了gtest.h文件,它聲明了測(cè)試框架。
#include <limits.h>
#include "sample1.h"
#include "gtest/gtest.h"
namespace {
//步驟2.使用TEST宏定義測(cè)試。
//TEST有兩個(gè)參數(shù):測(cè)試用例名稱 和 測(cè)試名稱。
//您可以使用一堆宏來(lái)指示測(cè)試的成功或失敗。
//EXPECT_TRUE和EXPECT_EQ是此類宏的示例。有關(guān)完整列表,請(qǐng)參見(jiàn)gtest.h。
//有關(guān)完整列表,請(qǐng)參見(jiàn)gtest.h。
//
//<技術(shù)細(xì)節(jié)>
//
//在Google測(cè)試中,測(cè)試被分組為測(cè)試用例。這就是我們
//保持測(cè)試代碼的有序性。你應(yīng)該進(jìn)行邏輯相關(guān)的測(cè)試
//進(jìn)入同一測(cè)試用例。
//
//測(cè)試用例名稱和測(cè)試名稱都應(yīng)該是有效的C++
//標(biāo)識(shí)符。而且你不應(yīng)該在名字中使用下劃線(_)。
//
//谷歌測(cè)試保證您定義的每個(gè)測(cè)試都準(zhǔn)確運(yùn)行
//一次,但不能保證測(cè)試的順序執(zhí)行。
//因此,您應(yīng)該以這樣的方式編寫測(cè)試
//他們的結(jié)果并不取決于他們的順序。
//
//</技術(shù)細(xì)節(jié)>
// Tests Factorial().
// Tests factorial of negative numbers.
TEST(FactorialTest, Negative) {
// This test is named "Negative", and belongs to the "FactorialTest"
// test case.FactorialTest 是測(cè)試用例名稱,Negative是測(cè)試名稱
EXPECT_EQ(1, Factorial(-5));
EXPECT_EQ(1, Factorial(-1));
EXPECT_GT(Factorial(-10), 0);
// <TechnicalDetails>
//
// EXPECT_EQ(expected, actual) is the same as
// EXPECT_TRUE((expected) == (actual))
//
//只是當(dāng)斷言失敗時(shí),它將打印預(yù)期值和實(shí)際值。這對(duì)調(diào)試非常有幫助。
//因此,在這種情況下,首選EXPECT_EQ。
//
//另一方面,EXPECT_TRUE接受任何布爾表達(dá)式,因此更通用。
//
//</技術(shù)細(xì)節(jié)>
}
// Tests factorial of 0.
TEST(FactorialTest, Zero) {
EXPECT_EQ(1, Factorial(0));
}
// Tests factorial of positive numbers.
TEST(FactorialTest, Positive) {
EXPECT_EQ(1, Factorial(1));
EXPECT_EQ(2, Factorial(2));
EXPECT_EQ(6, Factorial(3));
EXPECT_EQ(40320, Factorial(8));
}
// Tests IsPrime()
// Tests negative input.
TEST(IsPrimeTest, Negative) {
// This test belongs to the IsPrimeTest test case.
EXPECT_FALSE(IsPrime(-1));
EXPECT_FALSE(IsPrime(-2));
EXPECT_FALSE(IsPrime(INT_MIN));
}
// Tests some trivial cases.
TEST(IsPrimeTest, Trivial) {
EXPECT_FALSE(IsPrime(0));
EXPECT_FALSE(IsPrime(1));
EXPECT_TRUE(IsPrime(2));
EXPECT_TRUE(IsPrime(3));
}
// Tests positive input.
TEST(IsPrimeTest, Positive) {
EXPECT_FALSE(IsPrime(4));
EXPECT_TRUE(IsPrime(5));
EXPECT_FALSE(IsPrime(6));
EXPECT_TRUE(IsPrime(23));
}
} // namespace
//步驟3.在main()中調(diào)用RUN_ALL_TESTS()。
//
//我們通過(guò)鏈接src/gtest_main來(lái)實(shí)現(xiàn)這一點(diǎn)。cc文件,其中包括
//一個(gè)為我們調(diào)用RUN_ALL_TESTS()的main()函數(shù)。
//
//這將運(yùn)行您定義的所有測(cè)試,并打印結(jié)果,
//如果成功,則返回0,否則返回1。
//
//你注意到我們沒(méi)有注冊(cè)test嗎?這個(gè)
//RUN_ALL_TESTS()宏神奇地知道我們定義的所有測(cè)試
//定義。這不方便嗎?
五、gtest 的 sample2 解讀
??sample2是一個(gè)測(cè)試類的示例
// sample2.h
// A sample program demonstrating using Google C++ testing framework.
#ifndef GTEST_SAMPLES_SAMPLE2_H_
#define GTEST_SAMPLES_SAMPLE2_H_
#include <string.h>
// A simple string class.
class MyString {
private:
const char* c_string_;
const MyString& operator=(const MyString& rhs);
public:
// Clones a 0-terminated C string, allocating memory using new.
static const char* CloneCString(const char* a_c_string);
//
// C'tors
// The default c'tor constructs a NULL string.
MyString() : c_string_(nullptr) {}
// Constructs a MyString by cloning a 0-terminated C string.
explicit MyString(const char* a_c_string) : c_string_(nullptr) {
Set(a_c_string);
}
// Copy c'tor
MyString(const MyString& string) : c_string_(nullptr) {
Set(string.c_string_);
}
//
// D'tor. MyString is intended to be a final class, so the d'tor
// doesn't need to be virtual.
~MyString() { delete[] c_string_; }
// Gets the 0-terminated C string this MyString object represents.
const char* c_string() const { return c_string_; }
size_t Length() const { return c_string_ == nullptr ? 0 : strlen(c_string_); }
// 設(shè)置此MyString對(duì)象表示的以0(\0的ascii 碼是0)結(jié)尾的C字符串
void Set(const char* c_string);
};
#endif // GTEST_SAMPLES_SAMPLE2_H_
// sample2.cc
// A sample program demonstrating using Google C++ testing framework.
#include "sample2.h"
#include <string.h>
// 克隆以0結(jié)尾的C字符串,使用new分配內(nèi)存
const char* MyString::CloneCString(const char* a_c_string) {
if (a_c_string == nullptr) return nullptr;
const size_t len = strlen(a_c_string);
char* const clone = new char[ len + 1 ];
memcpy(clone, a_c_string, len + 1);
return clone;
}
//設(shè)置此MyString對(duì)象表示的以0結(jié)尾的C字符串
void MyString::Set(const char* a_c_string) {
// Makes sure this works when c_string == c_string_
const char* const temp = MyString::CloneCString(a_c_string);
delete[] c_string_;
c_string_ = temp;
}
// sample2_unittest.cc
// A sample program demonstrating using Google C++ testing framework.
//此示例演示如何為具有多個(gè)成員函數(shù)的類編寫更復(fù)雜的單元測(cè)試。
//
//通常,最好為類中的每個(gè)方法進(jìn)行一次測(cè)試。您不必完全這樣做,
//但這有助于保持測(cè)試的有序性。您還可以根據(jù)需要進(jìn)行額外的測(cè)試。
#include "sample2.h"
#include "gtest/gtest.h"
namespace {
// In this example, we test the MyString class (a simple string).
//下面將是一個(gè)測(cè)試用例,測(cè)試這個(gè)類,但有多個(gè)測(cè)試名稱,測(cè)試類的不同功能特性
// Tests the default c'tor.
TEST(MyString, DefaultConstructor) {
const MyString s;
// Asserts that s.c_string() returns NULL.
//
// <TechnicalDetails>
//
// If we write NULL instead of
//
// static_cast<const char *>(NULL)
//
//在這個(gè)斷言中,它將在gcc 3.4上生成一個(gè)警告
//原因是EXPECT_EQ需要知道其類型
//參數(shù),以便在失敗時(shí)打印它們。由于NULL是
//#define 0,編譯器將使用格式化程序函數(shù)
//int打印。然而,gcc認(rèn)為NULL應(yīng)該用作
//指針,而不是int,因此會(huì)警告
//
//問(wèn)題的根源是C++沒(méi)有區(qū)分
//整數(shù)0和空指針常量。不幸地
//我們必須接受這個(gè)事實(shí)。
//
//</技術(shù)細(xì)節(jié)>
EXPECT_STREQ(nullptr, s.c_string());
EXPECT_EQ(0u, s.Length());
}
const char kHelloString[] = "Hello, world!";
// Tests the c'tor that accepts a C string.
TEST(MyString, ConstructorFromCString) {
const MyString s(kHelloString);
EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
EXPECT_EQ(sizeof(kHelloString)/sizeof(kHelloString[0]) - 1,
s.Length());
}
// Tests the copy c'tor.
TEST(MyString, CopyConstructor) {
const MyString s1(kHelloString);
const MyString s2 = s1;
EXPECT_EQ(0, strcmp(s2.c_string(), kHelloString));
}
// Tests the Set method.
TEST(MyString, Set) {
MyString s;
s.Set(kHelloString);
EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
// Set should work when the input pointer is the same as the one
// already in the MyString object.
s.Set(s.c_string());
EXPECT_EQ(0, strcmp(s.c_string(), kHelloString));
// Can we set the MyString to NULL?
s.Set(nullptr);
EXPECT_STREQ(nullptr, s.c_string());
}
} // namespace
六、gtest 的其他sample解讀
??sample3-sample10也是不同的示例,學(xué)習(xí)時(shí)應(yīng)該按照順序?qū)W習(xí),后邊的示例會(huì)用到前邊示例的知識(shí)。學(xué)習(xí)每個(gè)示例時(shí),可以參考文件中的注釋內(nèi)容來(lái)理解。文章來(lái)源:http://www.zghlxwxcb.cn/news/detail-402959.html
//sample3_unittest.cc
//在這個(gè)例子中,我們使用了谷歌測(cè)試的一個(gè)更高級(jí)的特性,稱為測(cè)試夾具(test fixture)
//測(cè)試夾具是保存測(cè)試用例中所有測(cè)試共享的對(duì)象和函數(shù)的地方。使用測(cè)試夾具可以避免
//重復(fù)初始化和清理每個(gè)測(cè)試的公共對(duì)象所需的測(cè)試代碼。它對(duì)于定義測(cè)試需要調(diào)用的子
//程序也很有用。
//測(cè)試在代碼共享的意義上共享測(cè)試夾具,而不是數(shù)據(jù)共享。每個(gè)測(cè)試都有自己的夾具
//新副本。您不能期望由一個(gè)測(cè)試修改的數(shù)據(jù)傳遞到另一個(gè)測(cè)試,這是一個(gè)壞主意。
//
//這種設(shè)計(jì)的原因是測(cè)試應(yīng)該是獨(dú)立的和可重復(fù)的。特別是,一個(gè)測(cè)試不應(yīng)該因?yàn)榱?/span>
//一個(gè)測(cè)試的失敗而失敗。如果一個(gè)測(cè)試依賴于另一個(gè)測(cè)試產(chǎn)生的信息,那么這兩個(gè)
//測(cè)試真的應(yīng)該是一個(gè)大測(cè)試。
//
//用于指示測(cè)試成功/失敗的宏(EXPECT_TRUE、FAIL等)需要知道當(dāng)前測(cè)試是什么
//(當(dāng)Google測(cè)試打印測(cè)試結(jié)果時(shí),它會(huì)告訴您每個(gè)失敗屬于哪個(gè)測(cè)試)。從技術(shù)上
//講,這些宏調(diào)用Test類的成員函數(shù)。因此,不能在全局函數(shù)中使用它們。這就是為
//什么您應(yīng)該將測(cè)試子例程放在測(cè)試夾具中。
#include "sample3-inl.h"
#include "gtest/gtest.h"
namespace {
// To use a test fixture, derive a class from testing::Test.
class QueueTestSmpl3 : public testing::Test {
protected: // You should make the members protected s.t. they can be
// accessed from sub-classes.
// virtual void SetUp() will be called before each test is run. You
// should define it if you need to initialize the variables.
// Otherwise, this can be skipped.
void SetUp() override {
q1_.Enqueue(1);
q2_.Enqueue(2);
q2_.Enqueue(3);
}
// virtual void TearDown() will be called after each test is run.
// You should define it if there is cleanup work to do. Otherwise,
// you don't have to provide it.
//
// virtual void TearDown() {
// }
// A helper function that some test uses.
static int Double(int n) {
return 2*n;
}
// A helper function for testing Queue::Map().
void MapTester(const Queue<int> * q) {
// Creates a new queue, where each element is twice as big as the
// corresponding one in q.
const Queue<int> * const new_q = q->Map(Double);
// Verifies that the new queue has the same size as q.
ASSERT_EQ(q->Size(), new_q->Size());
// Verifies the relationship between the elements of the two queues.
for (const QueueNode<int>*n1 = q->Head(), *n2 = new_q->Head();
n1 != nullptr; n1 = n1->next(), n2 = n2->next()) {
EXPECT_EQ(2 * n1->element(), n2->element());
}
delete new_q;
}
// Declares the variables your tests want to use.
Queue<int> q0_;
Queue<int> q1_;
Queue<int> q2_;
};
// When you have a test fixture, you define a test using TEST_F
// instead of TEST.
// Tests the default c'tor.
TEST_F(QueueTestSmpl3, DefaultConstructor) {
// You can access data in the test fixture here.
EXPECT_EQ(0u, q0_.Size());
}
// Tests Dequeue().
TEST_F(QueueTestSmpl3, Dequeue) {
int * n = q0_.Dequeue();
EXPECT_TRUE(n == nullptr);
n = q1_.Dequeue();
ASSERT_TRUE(n != nullptr);
EXPECT_EQ(1, *n);
EXPECT_EQ(0u, q1_.Size());
delete n;
n = q2_.Dequeue();
ASSERT_TRUE(n != nullptr);
EXPECT_EQ(2, *n);
EXPECT_EQ(1u, q2_.Size());
delete n;
}
// Tests the Queue::Map() function.
TEST_F(QueueTestSmpl3, Map) {
MapTester(&q0_);
MapTester(&q1_);
MapTester(&q2_);
}
} // namespace
注:本文章參考了《朱老師物聯(lián)網(wǎng)大講堂》課程筆記,并結(jié)合了自己的實(shí)際開(kāi)發(fā)經(jīng)歷、百度百科以及網(wǎng)上他人的技術(shù)文章,綜合整理得到。如有侵權(quán),聯(lián)系刪除!水平有限,歡迎各位在評(píng)論區(qū)交流。文章來(lái)源地址http://www.zghlxwxcb.cn/news/detail-402959.html
到了這里,關(guān)于C++中的斷言機(jī)制與gtest單元測(cè)試的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!