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

歡迎訪問 生活随笔!

生活随笔

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

c/c++

玩转Google开源C++单元测试框架Google Test系列(gtest)之五 - 死亡测试

發(fā)布時(shí)間:2024/4/11 c/c++ 27 豆豆
生活随笔 收集整理的這篇文章主要介紹了 玩转Google开源C++单元测试框架Google Test系列(gtest)之五 - 死亡测试 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

一、前言

“死亡測(cè)試”名字比較恐怖,這里的“死亡”指的的是程序的崩潰。通常在測(cè)試過程中,我們需要考慮各種各樣的輸入,有的輸入可能直接導(dǎo)致程序崩潰,這時(shí)我們就需要檢查程序是否按照預(yù)期的方式掛掉,這也就是所謂的“死亡測(cè)試”。gtest的死亡測(cè)試能做到在一個(gè)安全的環(huán)境下執(zhí)行崩潰的測(cè)試案例,同時(shí)又對(duì)崩潰結(jié)果進(jìn)行驗(yàn)證。

二、使用的宏

Fatal assertion Nonfatal assertion Verifies
ASSERT_DEATH(statement, regex`); EXPECT_DEATH(statement, regex`); statement?crashes with the given error
ASSERT_EXIT(statement, predicate, regex`); EXPECT_EXIT(statement, predicate, regex`); statement?exits with the given error and its exit code matches?predicate

?

由于有些異常只在Debug下拋出,因此還提供了*_DEBUG_DEATH,用來處理Debug和Realease下的不同。

三、*_DEATH(statement, regex`)

1. statement是被測(cè)試的代碼語句

2. regex是一個(gè)正則表達(dá)式,用來匹配異常時(shí)在stderr中輸出的內(nèi)容

如下面的例子:?

void?Foo()
{
????
int?*pInt?=?0;
????
*pInt?=?42?;
}

TEST(FooDeathTest,?Demo)
{
????EXPECT_DEATH(Foo(),?
"");
}

?

重要:編寫死亡測(cè)試案例時(shí),TEST的第一個(gè)參數(shù),即testcase_name,請(qǐng)使用DeathTest后綴。原因是gtest會(huì)優(yōu)先運(yùn)行死亡測(cè)試案例,應(yīng)該是為線程安全考慮。

四、*_EXIT(statement, predicate, regex`)

1. statement是被測(cè)試的代碼語句

2. predicate 在這里必須是一個(gè)委托,接收int型參數(shù),并返回bool。只有當(dāng)返回值為true時(shí),死亡測(cè)試案例才算通過。gtest提供了一些常用的predicate:

testing::ExitedWithCode(exit_code)


如果程序正常退出并且退出碼與exit_code相同則返回?true

testing::KilledBySignal(signal_number)??//?Windows下不支持

?
如果程序被signal_number信號(hào)kill的話就返回true

3. regex是一個(gè)正則表達(dá)式,用來匹配異常時(shí)在stderr中輸出的內(nèi)容

這里, 要說明的是,*_DEATH其實(shí)是對(duì)*_EXIT進(jìn)行的一次包裝,*_DEATH的predicate判斷進(jìn)程是否以非0退出碼退出或被一個(gè)信號(hào)殺死。

例子:

TEST(ExitDeathTest,?Demo)
{
????EXPECT_EXIT(_exit(
1),??testing::ExitedWithCode(1),??"");
}

?

五、*_DEBUG_DEATH

先來看定義:

#ifdef?NDEBUG

#define?EXPECT_DEBUG_DEATH(statement,?regex)?\
??
do?{?statement;?}?while?(false)

#define?ASSERT_DEBUG_DEATH(statement,?regex)?\
??
do?{?statement;?}?while?(false)

#else

#define?EXPECT_DEBUG_DEATH(statement,?regex)?\
??EXPECT_DEATH(statement,?regex)

#define?ASSERT_DEBUG_DEATH(statement,?regex)?\
??ASSERT_DEATH(statement,?regex)

#endif??//?NDEBUG?for?EXPECT_DEBUG_DEATH

?

可以看到,在Debug版和Release版本下, *_DEBUG_DEATH的定義不一樣。因?yàn)楹芏喈惓V粫?huì)在Debug版本下拋出,而在Realease版本下不會(huì)拋出,所以針對(duì)Debug和Release分別做了不同的處理。看gtest里自帶的例子就明白了:

int?DieInDebugElse12(int*?sideeffect)?{
????
if?(sideeffect)?*sideeffect?=?12;
#ifndef?NDEBUG
????GTEST_LOG_(FATAL,?
"debug?death?inside?DieInDebugElse12()");
#endif??//?NDEBUG
????
return?12;
}

TEST(TestCase,?TestDieOr12WorksInDgbAndOpt)
{
????
int?sideeffect?=?0;
????
//?Only?asserts?in?dbg.
????EXPECT_DEBUG_DEATH(DieInDebugElse12(&sideeffect),?"death");

????#ifdef?NDEBUG
????
//?opt-mode?has?sideeffect?visible.
????EXPECT_EQ(12,?sideeffect);
????
#else
????
//?dbg-mode?no?visible?sideeffect.
????EXPECT_EQ(0,?sideeffect);
????
#endif
}

?

六、關(guān)于正則表達(dá)式

在POSIX系統(tǒng)(Linux, Cygwin, 和 Mac)中,gtest的死亡測(cè)試中使用的是POSIX風(fēng)格的正則表達(dá)式,想了解POSIX風(fēng)格表達(dá)式可參考:?

1.?POSIX extended regular expression

2.?Wikipedia entry.

在Windows系統(tǒng)中,gtest的死亡測(cè)試中使用的是gtest自己實(shí)現(xiàn)的簡(jiǎn)單的正則表達(dá)式語法。 相比POSIX風(fēng)格,gtest的簡(jiǎn)單正則表達(dá)式少了很多內(nèi)容,比如?("x|y"), ("(xy)"), ("[xy]") 和("x{5,7}")都不支持。

下面是簡(jiǎn)單正則表達(dá)式支持的一些內(nèi)容:


matches any literal character?c
\\d matches any decimal digit
\\D matches any character that's not a decimal digit
\\f matches?\f
\\n matches?\n
\\r matches?\r
\\s matches any ASCII whitespace, including?\n
\\S matches any character that's not a whitespace
\\t matches?\t
\\v matches?\v
\\w matches any letter,?_, or decimal digit
\\W matches any character that?\\w?doesn't match
\\c matches any literal character?c, which must be a punctuation
. matches any single character except?\n
A? matches 0 or 1 occurrences of?A
A* matches 0 or many occurrences of?A
A+ matches 1 or many occurrences of?A
^ matches the beginning of a string (not that of each line)
$ matches the end of a string (not that of each line)
xy matches?x?followed by?y

?

gtest定義兩個(gè)宏,用來表示當(dāng)前系統(tǒng)支持哪套正則表達(dá)式風(fēng)格:

1. POSIX風(fēng)格:GTEST_USES_POSIX_RE?= 1?

2. Simple風(fēng)格:GTEST_USES_SIMPLE_RE=1

七、死亡測(cè)試運(yùn)行方式

1. fast方式(默認(rèn)的方式)

testing::FLAGS_gtest_death_test_style?=?"fast";

2. threadsafe方式

testing::FLAGS_gtest_death_test_style?=?"threadsafe";


你可以在?main()?里為所有的死亡測(cè)試設(shè)置測(cè)試形式,也可以為某次測(cè)試單獨(dú)設(shè)置。Google Test會(huì)在每次測(cè)試之前保存這個(gè)標(biāo)記并在測(cè)試完成后恢復(fù),所以你不需要去管這部分工作 。如:

TEST(MyDeathTest,?TestOne)?{
??testing::FLAGS_gtest_death_test_style?
=?"threadsafe";
??
//?This?test?is?run?in?the?"threadsafe"?style:
??ASSERT_DEATH(ThisShouldDie(),?"");
}

TEST(MyDeathTest,?TestTwo)?{
??
//?This?test?is?run?in?the?"fast"?style:
??ASSERT_DEATH(ThisShouldDie(),?"");
}

int?main(int?argc,?char**?argv)?{
??testing::InitGoogleTest(
&argc,?argv);
??testing::FLAGS_gtest_death_test_style?
=?"fast";
??
return?RUN_ALL_TESTS();
}

?

八、注意事項(xiàng)

1. 不要在死亡測(cè)試?yán)镝尫艃?nèi)存。

2. 在父進(jìn)程里再次釋放內(nèi)存。

3. 不要在程序中使用內(nèi)存堆檢查。

九、總結(jié)

關(guān)于死亡測(cè)試,gtest官方的文檔已經(jīng)很詳細(xì)了,同時(shí)在源碼中也有大量的示例。如想了解更多的請(qǐng)參考官方的文檔,或是直接看gtest源碼。

簡(jiǎn)單來說,通過*_DEATH(statement, regex`)和*_EXIT(statement, predicate, regex`),我們可以非常方便的編寫導(dǎo)致崩潰的測(cè)試案例,并且在不影響其他案例執(zhí)行的情況下,對(duì)崩潰案例的結(jié)果進(jìn)行檢查。

總結(jié)

以上是生活随笔為你收集整理的玩转Google开源C++单元测试框架Google Test系列(gtest)之五 - 死亡测试的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。

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