日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > c/c++ >内容正文

c/c++

Google C++单元测试框架GoogleTest---AdvancedGuide(译文)上

發(fā)布時(shí)間:2024/1/17 c/c++ 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Google C++单元测试框架GoogleTest---AdvancedGuide(译文)上 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

本文是gtest高級(jí)測(cè)試指南的譯文,由于文章太長(zhǎng),分上下兩部分。

一、簡(jiǎn)介

? ?本文檔將向您展示更多的斷言,以及如何構(gòu)造復(fù)雜的失敗消息,傳播致命的故障,重用和加速您的測(cè)試夾具,并在您的測(cè)試使用各種標(biāo)志。

二、更多斷言

? 本節(jié)包括一些不太常用,但仍然重要的斷言。

? 2.1 顯式成功和失敗

? 這三個(gè)斷言實(shí)際上不測(cè)試值或表達(dá)式。 相反,它們直接產(chǎn)生成功或失敗。 與實(shí)際執(zhí)行測(cè)試的宏類似,您可以將自定義失敗消息流入它們。

SUCCEED();

生成成功。 這不會(huì)使整體測(cè)試成功。 只有當(dāng)測(cè)試在其執(zhí)行期間沒有任何斷言失敗時(shí),測(cè)試才被認(rèn)為是成功的。

注意:SUCCEED()是純紀(jì)錄片,目前不生成任何用戶可見的輸出。 但是,我們可能會(huì)在未來向Google Test的輸出中添加SUCCEED()消息。

FAIL(); ADD_FAILURE(); ADD_FAILURE_AT("file_path",line_number);

FAIL()產(chǎn)生致命故障,而ADD_FAILURE()和ADD_FAILURE_AT()產(chǎn)生非致命故障。 當(dāng)控制流而不是布爾表達(dá)式確定測(cè)試的成功或失敗時(shí),這些是有用的。 例如,您可能想要寫如下:

switch(expression) {case 1: ... some checks ...case 2: ... some other checks...default: FAIL() << "We shouldn't get here."; }

注意:你只能在返回void的函數(shù)中使用FAIL()。 有關(guān)詳細(xì)信息,請(qǐng)參閱?Assertion Placement section?部分。

?2.2 異常斷言

這些用于驗(yàn)證一段代碼拋出(或不拋出)給定類型的異常:

Fatal assertionNonfatal assertionVerifies
ASSERT_THROW(statement,?exception_type);EXPECT_THROW(statement,?exception_type);statement?throws an exception of the given type
ASSERT_ANY_THROW(statement);EXPECT_ANY_THROW(statement);statement?throws an exception of any type
ASSERT_NO_THROW(statement);EXPECT_NO_THROW(statement);statement?doesn't throw any exception

Examples:

ASSERT_THROW(Foo(5), bar_exception);EXPECT_NO_THROW({int n = 5;Bar(&n); });  

三、更好的錯(cuò)誤消息的謂詞斷言

雖然Google測(cè)試有一套豐富的斷言,但它們永遠(yuǎn)不可能完整,因?yàn)樗豢赡?#xff08;也不是一個(gè)好主意)預(yù)測(cè)用戶可能遇到的所有情況。 因此,有時(shí)用戶必須使用EXPECT_TRUE()來檢查復(fù)雜表達(dá)式,因?yàn)槿鄙俑玫暮辍?這有一個(gè)問題,沒有顯示你的表達(dá)式的部分的值,使得很難理解什么錯(cuò)誤。 作為解決方法,一些用戶選擇自己構(gòu)造失敗消息,將其流式傳輸?shù)紼XPECT_TRUE()。 然而,這是尷尬,特別是當(dāng)表達(dá)式有副作用或評(píng)價(jià)昂貴。

Google測(cè)試提供三種不同的選項(xiàng)來解決這個(gè)問題:

?3.1使用現(xiàn)有的布爾函數(shù)

如果你已經(jīng)有一個(gè)函數(shù)或函數(shù)返回bool(或一個(gè)可以隱式轉(zhuǎn)換為bool的類型),你可以在謂詞斷言中使用它來獲得免費(fèi)打印的函數(shù)參數(shù):

Fatal assertionNonfatal assertionVerifies
ASSERT_PRED1(pred1, val1);EXPECT_PRED1(pred1, val1);pred1(val1)?returns true
ASSERT_PRED2(pred2, val1, val2);EXPECT_PRED2(pred2, val1, val2);pred2(val1, val2)?returns true
.........

在上面,predn是一個(gè)n元謂詞函數(shù)或函子,其中val1,val2,...和valn是它的參數(shù)。 如果謂詞在應(yīng)用于給定參數(shù)時(shí)返回true,則斷言成功,否則失敗。 當(dāng)斷言失敗時(shí),它打印每個(gè)參數(shù)的值。 在任何一種情況下,參數(shù)只計(jì)算一次。

Here's an example:

// Returns true iff m and n have no common divisors except 1. bool MutuallyPrime(int m, int n) { ... } const int a = 3; const int b = 4; const int c = 10;

斷言EXPECT_PRED2(Mutual Prime,a,b); 將成功,而斷言EXPECT_PRED2(MutuallyPrime,b,c); 將失敗。

!MutuallyPrime(b, c) is false, whereb is 4c is 10 

注意:

?1. 如果在使用ASSERT_PRED *或EXPECT_PRED *時(shí)看到編譯器錯(cuò)誤“no matching function to call(無匹配函數(shù)調(diào)用)”,請(qǐng)參閱此常見問題解答?this FAQ?以了解如何解決它。
?2. 目前我們只提供arity <= 5的謂詞斷言。如果你需要更高級(jí)的斷言,讓我們知道。

3.2 使用返回AssertionResult的函數(shù)

雖然EXPECT_PRED *()和friends對(duì)快速工作很方便,但是語(yǔ)法不令人滿意:你必須使用不同的宏不同的arities,它感覺更像Lisp而不是C ++。 :: testing :: AssertionResult類解決了這個(gè)問題。

AssertionResult對(duì)象表示斷言的結(jié)果(無論它是成功還是失敗,以及相關(guān)聯(lián)的消息)。 您可以使用以下工廠函數(shù)之一創(chuàng)建AssertionResult:

namespace testing {// Returns an AssertionResult object to indicate that an assertion has // succeeded. AssertionResult AssertionSuccess();// Returns an AssertionResult object to indicate that an assertion has // failed. AssertionResult AssertionFailure();}

然后,您可以使用<<運(yùn)算符將消息流式傳輸?shù)紸ssertionResult對(duì)象。

要在布爾斷言(例如EXPECT_TRUE())中提供更多可讀消息,請(qǐng)編寫一個(gè)返回AssertionResult而不是bool的謂詞函數(shù)。 例如,如果您將IsEven()定義為:

::testing::AssertionResult IsEven(int n) {if ((n % 2) == 0)return ::testing::AssertionSuccess();elsereturn ::testing::AssertionFailure() << n << " is odd"; }

而不是:

bool IsEven(int n) {return (n % 2) == 0; }

  the failed assertion?EXPECT_TRUE(IsEven(Fib(4)))?will print:

Value of: IsEven(Fib(4))Actual: false (*3 is odd*)Expected: true

  instead of a more opaque:

Value of: IsEven(Fib(4))Actual: falseExpected: true

  如果您希望在EXPECT FALSE和ASSERT_FALSE中看到提供信息的消息,并且在成功的情況下使謂詞變慢,您可以提供一個(gè)成功消息:

::testing::AssertionResult IsEven(int n) {if ((n % 2) == 0)return ::testing::AssertionSuccess() << n << " is even";elsereturn ::testing::AssertionFailure() << n << " is odd"; }

  Then the statement?EXPECT_FALSE(IsEven(Fib(6)))?will print

Value of: IsEven(Fib(6))Actual: true (8 is even)Expected: false

3.3 使用謂詞格式化

? ?如果你發(fā)現(xiàn)由(ASSERT | EXPECT)_PRED *和(ASSERT | EXPECT)_(TRUE | FALSE)生成的默認(rèn)消息不令人滿意,或者您的謂詞的某些參數(shù)不支持流到ostream,您可以使用以下謂詞 - 格式化程序斷言 以完全自定義消息的格式化:

Fatal assertionNonfatal assertionVerifies
ASSERT_PRED_FORMAT1(pred_format1, val1);EXPECT_PRED_FORMAT1(pred_format1, val1);pred_format1(val1)?is successful
ASSERT_PRED_FORMAT2(pred_format2, val1, val2);EXPECT_PRED_FORMAT2(pred_format2, val1, val2);pred_format2(val1, val2)?is successful
.........

這和前兩組宏的區(qū)別是,不是一個(gè)謂詞,(ASSERT | EXPECT)_PRED_FORMAT *采用謂詞格式化器(pred_formatn),它是一個(gè)函數(shù)或函數(shù)簽名:

::testing::AssertionResult PredicateFormattern(const char*expr1, const char*expr2, ... const char*exprn, T1val1, T2val2, ... Tnvaln);

四、浮點(diǎn)比較

比較浮點(diǎn)數(shù)是棘手的。 由于舍入誤差,兩個(gè)浮點(diǎn)不太可能完全匹配。 因此,ASSERT_EQ的幼稚比較通常不起作用。 并且由于浮點(diǎn)可以具有寬的值范圍,沒有單個(gè)固定誤差界限工作。 最好通過固定的相對(duì)誤差界限進(jìn)行比較,除了接近0的值由于精度的損失。

一般來說,對(duì)于浮點(diǎn)比較有意義,用戶需要仔細(xì)選擇誤差界限。 如果他們不想要或關(guān)心,根據(jù)最后地點(diǎn)(ULP)中的單位進(jìn)行比較是一個(gè)很好的默認(rèn)值,Google測(cè)試提供了斷言來做到這一點(diǎn)。 關(guān)于ULP的完整詳細(xì)信息相當(dāng)長(zhǎng); 如果你想了解更多,請(qǐng)參閱這篇關(guān)于浮動(dòng)比較的文章?this article on float comparison.。

Floating-Point Macros

Fatal assertionNonfatal assertionVerifies
ASSERT_FLOAT_EQ(val1, val2);EXPECT_FLOAT_EQ(val1, val2);the two?float?values are almost equal
ASSERT_DOUBLE_EQ(val1, val2);EXPECT_DOUBLE_EQ(val1, val2);the two?double?values are almost equal

“幾乎相等”是指兩個(gè)值彼此在4個(gè)ULP內(nèi)。

以下斷言允許您選擇可接受的誤差界限:

Fatal assertionNonfatal assertionVerifies
ASSERT_NEAR(val1, val2, abs_error);EXPECT_NEAR(val1, val2, abs_error);the difference between?val1?and?val2?doesn't exceed the given absolute error

。。。。太多,需要時(shí)再去看。

五、Windows HRESULT斷言

這些斷言測(cè)試HRESULT成功或失敗。

Fatal assertionNonfatal assertionVerifies
ASSERT_HRESULT_SUCCEEDED(expression);EXPECT_HRESULT_SUCCEEDED(expression);expression?is a success?HRESULT
ASSERT_HRESULT_FAILED(expression);EXPECT_HRESULT_FAILED(expression);expression?is a failure?HRESULT

生成的輸出包含與expression返回的HRESULT代碼相關(guān)聯(lián)的人工可讀錯(cuò)誤消息。

You might use them like this:

CComPtr shell; ASSERT_HRESULT_SUCCEEDED(shell.CoCreateInstance(L"Shell.Application")); CComVariant empty; ASSERT_HRESULT_SUCCEEDED(shell->ShellExecute(CComBSTR(url), empty, empty, empty, empty));

六、類型斷言

?

::testing::StaticAssertTypeEq<T1, T2>();

您可以調(diào)用該函數(shù),來聲稱斷言類型T1和T2是相同的。 如果滿足斷言,該函數(shù)不執(zhí)行任何操作。 如果類型不同,函數(shù)調(diào)用將無法編譯,編譯器錯(cuò)誤消息(取決于編譯器)將顯示T1和T2的實(shí)際值。 這主要在模板代碼中有用。

注意:當(dāng)在類模板或函數(shù)模板的成員函數(shù)中使用時(shí),StaticAssertTypeEq <T1,T2>()僅在函數(shù)實(shí)例化時(shí)有效。 例如,給定:

template <typename T> class Foo {public:void Bar() { ::testing::StaticAssertTypeEq<int, T>(); } };

the code:

void Test1() { Foo<bool> foo; }

將不會(huì)生成編譯器錯(cuò)誤,因?yàn)镕oo <bool> :: Bar()永遠(yuǎn)不會(huì)實(shí)際實(shí)例化。 相反,您需要:

void Test2() { Foo<bool> foo; foo.Bar(); }

導(dǎo)致編譯器錯(cuò)誤。

七、Assertion Placement(斷言放置)

你可以在任何C ++函數(shù)中使用斷言。 特別地,它不必是測(cè)試夾具類的方法。 一個(gè)約束是生成致命故障(FAIL *和ASSERT_ *)的斷言只能在void返回函數(shù)中使用。 這是Google測(cè)試不使用exceptions的后果。 如果將它放在一個(gè)非void函數(shù)中,你會(huì)得到一個(gè)令人困惑的編譯錯(cuò)誤,如“error: void value not ignored as it ought to be”。

如果需要在返回非void的函數(shù)中使用斷言,一個(gè)選項(xiàng)是使函數(shù)返回out參數(shù)中的值。 例如,您可以將T2 Foo(T1 x)重寫為void Foo(T1 x,T2 * result)。 你需要確保* result包含一些合理的值,即使該函數(shù)過早返回。 由于函數(shù)現(xiàn)在返回void,你可以在它里面使用任何斷言。

如果更改函數(shù)的類型不是一個(gè)選項(xiàng),則應(yīng)該使用生成非致命失敗的斷言,例如ADD_FAILURE *和EXPECT_ *。

注意:根據(jù)C ++語(yǔ)言規(guī)范,構(gòu)造函數(shù)和析構(gòu)函數(shù)不被視為void返回函數(shù),因此您不能在其中使用致命斷言。 如果你嘗試,你會(huì)得到一個(gè)編譯錯(cuò)誤。 一個(gè)簡(jiǎn)單的解決方法是將構(gòu)造函數(shù)或析構(gòu)函數(shù)的整個(gè)體轉(zhuǎn)移到私有void返回方法。 然而,你應(yīng)該意識(shí)到,構(gòu)造函數(shù)中的致命斷言失敗并不會(huì)終止當(dāng)前的測(cè)試,正如你的直覺所暗示的那樣; 它只是從構(gòu)造函數(shù)早期返回,可能使您的對(duì)象處于部分構(gòu)造狀態(tài)。 同樣,析構(gòu)函數(shù)中的致命斷言失敗可能使您的對(duì)象處于部分破壞狀態(tài)。 在這些情況下仔細(xì)使用斷言!

八、教學(xué)Google測(cè)試如何打印您的值

當(dāng)測(cè)試聲明(如EXPECT_EQ)失敗時(shí),Google Test會(huì)打印參數(shù)值以幫助您調(diào)試。 它使用用戶可擴(kuò)展值打印機(jī)。

此打印機(jī)知道如何打印內(nèi)置的C ++類型,native數(shù)組,STL容器和任何支持<<運(yùn)算符的類型。 對(duì)于其他類型,它打印值中的原始字節(jié),并希望用戶可以計(jì)算出來。

如前所述,打印機(jī)是可擴(kuò)展的。 這意味著你可以教它做一個(gè)更好的工作,打印你的特定類型,而不是轉(zhuǎn)儲(chǔ)字節(jié)。 要做到這一點(diǎn),定義<<您的類型:

#include <iostream>namespace foo {class Bar { ... }; // We want Google Test to be able to print instances of this.// It's important that the << operator is defined in the SAME // namespace that defines Bar. C++'s look-up rules rely on that. ::std::ostream& operator<<(::std::ostream& os, const Bar& bar) {return os << bar.DebugString(); // whatever needed to print bar to os }} // namespace foo

有時(shí),這可能不是一個(gè)選項(xiàng):你的團(tuán)隊(duì)可能認(rèn)為它的壞風(fēng)格有一個(gè)<<運(yùn)算符的Bar,或者Bar可能已經(jīng)有一個(gè)<<運(yùn)算符,不做你想要的(你不能改變它)。 如果是這樣,您可以定義一個(gè)PrintTo()函數(shù),如下所示:

#include <iostream>namespace foo {class Bar { ... };// It's important that PrintTo() is defined in the SAME // namespace that defines Bar. C++'s look-up rules rely on that. void PrintTo(const Bar& bar, ::std::ostream* os) {*os << bar.DebugString(); // whatever needed to print bar to os }} // namespace foo 

如果您定義了<<和PrintTo(),后者將在Google測(cè)試時(shí)使用。 這允許您自定義值如何顯示在Google測(cè)試的輸出中,而不影響依賴于其<<運(yùn)算符的行為的代碼。

如果你想使用Google Test的值打印機(jī)自己打印一個(gè)值x,只需調(diào)用:: testing :: PrintToString(x),它返回一個(gè)std :: string:

vector<pair<Bar, int> > bar_ints = GetBarIntVector();EXPECT_TRUE(IsCorrectBarIntVector(bar_ints))<< "bar_ints = " << ::testing::PrintToString(bar_ints);

Extending Google Test by Handling Test Events

這個(gè)挺復(fù)雜,寫在單獨(dú)的文檔中:?http://www.cnblogs.com/jycboy/p/gtest_handlingEvent.html

?

轉(zhuǎn)載請(qǐng)注明出處:http://www.cnblogs.com/jycboy/p/gtest_AdvancedGuide.html

?

轉(zhuǎn)載于:https://www.cnblogs.com/jycboy/p/gtest_AdvancedGuide.html

創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎(jiǎng)勵(lì)來咯,堅(jiān)持創(chuàng)作打卡瓜分現(xiàn)金大獎(jiǎng)

總結(jié)

以上是生活随笔為你收集整理的Google C++单元测试框架GoogleTest---AdvancedGuide(译文)上的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。