簡(jiǎn)介: 為什么谷歌 c + + 測(cè)試框架?
谷歌 c + + 測(cè)試框架可以幫助你寫出更好的 c + + 測(cè)試。
無(wú)論是否您工作在 Linux 上,Windows 或 Mac,如果您編寫 c + + 代碼,谷歌測(cè)試可以幫助你。
是什么讓一個(gè)好的測(cè)試,和谷歌 c + + 測(cè)試框架如何適應(yīng)呢?我們相信:
- 測(cè)試應(yīng)獨(dú)立和可重復(fù)。它是痛苦調(diào)試成功或失敗的其他測(cè)試結(jié)果的測(cè)試。谷歌 c + + 測(cè)試框架通過(guò)不同的對(duì)象上運(yùn)行每個(gè)隔離測(cè)試。當(dāng)測(cè)試失敗時(shí),谷歌 c + + 測(cè)試框架允許您在隔離的快速調(diào)試中運(yùn)行它。
- 測(cè)試應(yīng)舉辦井和反映測(cè)試代碼的結(jié)構(gòu)。谷歌 c + + 測(cè)試框架可以共享數(shù)據(jù)和子例程的測(cè)試用例入組相關(guān)的測(cè)試。這種常見模式很容易認(rèn)出并使測(cè)試易于維護(hù)。這種一致性人切換項(xiàng)目,并開始一個(gè)新的代碼庫(kù)的工作時(shí)特別有用。
- 測(cè)試應(yīng)攜帶和可重復(fù)使用。開放源代碼社區(qū)有很多平臺(tái)無(wú)關(guān)的代碼,其測(cè)試也應(yīng)平臺(tái)無(wú)關(guān)。谷歌 c + + 測(cè)試框架在不同的操作系統(tǒng),具有不同的編譯器 (gcc、 MSVC,和其他人),有無(wú)異常,那么谷歌 c + + 測(cè)試框架的測(cè)試可以輕松地使用各種配置。(注意當(dāng)前版本只包含生成腳本用于 Linux — — 我們正在積極地對(duì)其他平臺(tái)的腳本)。
- 當(dāng)測(cè)試失敗時(shí),他們應(yīng)盡可能提供問題盡可能多的信息。谷歌 c + + 測(cè)試框架不只是第一次測(cè)試失敗。相反,它只停止當(dāng)前測(cè)試,并繼續(xù)下一步。您還可以設(shè)置測(cè)試該報(bào)告非致命故障后,當(dāng)前測(cè)試?yán)^續(xù)。因此,您可以檢測(cè)并修復(fù)單個(gè)編譯編輯-運(yùn)行周期中的多個(gè) bug。
- 測(cè)試框架應(yīng)解放測(cè)試作家從內(nèi)務(wù)管理家務(wù),讓他們專注于測(cè)試的內(nèi)容。谷歌 c + + 測(cè)試框架自動(dòng)跟蹤的所有測(cè)試定義的并且不需要用戶枚舉它們?yōu)榱诉\(yùn)行它們。
- 測(cè)試應(yīng)快速。與谷歌 c + + 測(cè)試框架,可以在測(cè)試之間重用共享的資源并支付集上/淚下只有一次,而不做測(cè)試相互依賴。
由于谷歌 c + + 測(cè)試框架基于流行 xUnit 建筑,你會(huì)感覺右在家里如果您使用過(guò) JUnit 或前的 PyUnit。如果不是,它將帶你了解的基本知識(shí)和開始約 10 分鐘。所以我們?nèi)グ?!
注:我們有時(shí)稱為 Google c + + 測(cè)試框架非正式谷歌測(cè)試.
建立一個(gè)新的測(cè)試項(xiàng)目
要編寫一個(gè)使用谷歌測(cè)試的測(cè)試程序,您需要將谷歌測(cè)試編譯成庫(kù)和鏈接您的測(cè)試與它。對(duì)于一些受歡迎的生成系統(tǒng)生成文件,我們提供: msvc /Visual studio, xcode /為 Mac Xcode,使 /為 GNU,指令 / Borland c + + 生成器,和 autotools 腳本 (已過(guò)時(shí)) 和CMakeLists.txt的 CMake (推薦) 谷歌測(cè)試的根目錄中。如果您生成系統(tǒng)不在此列表中,您可以看一看學(xué)習(xí) Google 測(cè)試應(yīng)如何編譯使/生成文件(基本上您要編譯src/gtest-all.cc與GTEST_ROOT和GTEST_ROOT/包含在標(biāo)題搜索路徑中,其中GTEST_ROOT是 Google 測(cè)試根目錄)。
一旦您將能夠編譯谷歌測(cè)試庫(kù),應(yīng)創(chuàng)建一個(gè)項(xiàng)目,或您的測(cè)試程序生成目標(biāo)。請(qǐng)確保你有GTEST_ROOT/包含標(biāo)題搜索路徑中,以便您的測(cè)試進(jìn)行編譯時(shí),編譯器可以找到"gtest/gtest.h" 。設(shè)置您的測(cè)試項(xiàng)目與谷歌測(cè)試庫(kù)鏈接 (例如,在 Visual Studio 中,這通過(guò)在gtest.vcproj上添加依賴項(xiàng)).
如果您還有問題,看看如何測(cè)試 Google 測(cè)試生成并將其用作示例。
基本概念
在使用谷歌測(cè)試時(shí),你開始通過(guò)編寫斷言,哪些語(yǔ)句,檢查是否一個(gè)條件為真。斷言結(jié)果可以成功、非致命故障或致命故障。如果發(fā)生致命故障,它將中止當(dāng)前的功能 ;否則,程序繼續(xù)正常。
測(cè)試使用斷言來(lái)驗(yàn)證測(cè)試的代碼的行為。如果測(cè)試崩潰或已失敗的斷言,那么它將失敗;否則為它會(huì)成功.
測(cè)試用例包含一個(gè)或多個(gè)測(cè)試。您應(yīng)將測(cè)試用例反映測(cè)試代碼的結(jié)構(gòu)組成您的測(cè)試。當(dāng)多個(gè)測(cè)試的測(cè)試用例需要共同的對(duì)象和子例程時(shí),你能把它們測(cè)試夾具的類。
測(cè)試程序可以包含多個(gè)測(cè)試用例。
我們現(xiàn)在將說(shuō)明如何編寫一個(gè)測(cè)試程序,開始在個(gè)別論斷一級(jí)和建立測(cè)試和測(cè)試用例。
斷言
谷歌測(cè)試斷言是類似于函數(shù)調(diào)用的宏。您通過(guò)使其行為的斷言測(cè)試類或函數(shù)。當(dāng)斷言失敗時(shí),谷歌測(cè)試打印斷言的源文件和行號(hào)的位置,連同失敗消息。您也可以提供自定義失敗消息,將追加到谷歌測(cè)試郵件。
斷言測(cè)試同樣的事情,但有不同的效果,對(duì)當(dāng)前函數(shù)的成對(duì)出現(xiàn)。ASSERT_ *版本生成失敗時(shí),致命故障和中止當(dāng)前函數(shù)。EXPECT_ *版本生成非致命的失敗,不中止當(dāng)前函數(shù)。EXPECT_ *通常首選,因?yàn)樗鼈冊(cè)试S多個(gè)測(cè)試中報(bào)告故障。但是,您應(yīng)該使用ASSERT_ *如果不合情理,則斷言失敗后繼續(xù)。
由于失敗ASSERT_ *從當(dāng)前函數(shù)立即返回,可能會(huì)跳過(guò)清理代碼后,它可能會(huì)導(dǎo)致空間泄漏。取決于漏油的性質(zhì),它可能會(huì)或可能不值得修復(fù)-所以記住這一點(diǎn)如果你除了斷言錯(cuò)誤堆檢查器錯(cuò)誤。
若要提供自定義失敗消息,只是流它成宏使用<<運(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ù)?tt style="font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 66em; ">ostream的東西可以進(jìn)行流式傳輸?shù)綌嘌院?— — 尤其是 C 字符串和字符串對(duì)象。如果寬字符串 (wchar_t *, TCHAR *在UNICODE模式下,在 Windows 中或std::wstring) 流入到一個(gè)斷言,它將被翻譯為 utf-8 打印時(shí)。
基本的斷言
這些斷言做真/假的基本條件測(cè)試。
致命的斷言 | 非致命的斷言 | 驗(yàn)證 |
ASSERT_TRUE (條件); | EXPECT_TRUE (條件); | 條件為真 |
ASSERT_FALSE (條件); | EXPECT_FALSE (條件); | 條件為假 |
請(qǐng)記住,當(dāng)他們失敗時(shí), ASSERT_ *收益率出現(xiàn)致命故障和返回從當(dāng)前函數(shù),而EXPECT_ *產(chǎn)量為非致命的失敗,從而能夠繼續(xù)運(yùn)行功能。在任一情況下,斷言失敗意味著它包含測(cè)試失敗。
可用性: Linux、 Windows、 mac。
二進(jìn)制比較
本節(jié)介紹比較兩個(gè)值的斷言。
致命的斷言 | 非致命的斷言 | 驗(yàn)證 |
ASSERT_EQ (, 預(yù)期實(shí)際); | EXPECT_EQ (, 預(yù)期實(shí)際); | 預(yù)期= =實(shí)際 |
ASSERT_NE (, val1 val2); | EXPECT_NE (, val1 val2); | val1! =val2 |
ASSERT_LT (, val1 val2); | EXPECT_LT (, val1 val2); | val1<val2 |
ASSERT_LE (, val1 val2); | EXPECT_LE (, val1 val2); | val1< =val2 |
ASSERT_GT (, val1 val2); | EXPECT_GT (, val1 val2); | val1>val2 |
ASSERT_GE (, val1 val2); | EXPECT_GE (, val1 val2); | val1> =val2 |
故障時(shí),事件中谷歌測(cè)試打印在val1和val2 。ASSERT_EQ * EXPECT_EQ * (及其他所有我們稍后介紹的平等斷言),您應(yīng)將您要測(cè)試的實(shí)際位置的表達(dá)式放并把其預(yù)期的價(jià)值放在預(yù)期,作為谷歌測(cè)試失敗的消息非常適合于本公約。
值參數(shù)必須是可比的說(shuō)法比較運(yùn)算符的否則你會(huì)編譯器錯(cuò)誤。我們需要支持的參數(shù)使用<<以來(lái) v1.6.0 運(yùn)算符的流ostream,但它已不再需要 (如<<是支持,它將調(diào)用,則斷言失敗時(shí)打印參數(shù) ; 否則將嘗試將其打印出來(lái)的最佳方法,它可以在谷歌測(cè)試。更多詳細(xì)信息以及如何自定義參數(shù)的打印,請(qǐng)參閱此 Google 模仿食譜.).
如果您定義相應(yīng)的比較運(yùn)算符,這些斷言可以使用用戶定義的類型,但僅限于 (例如= =, <,等等)。如果定義了相應(yīng)的運(yùn)算符,則更傾向于使用ASSERT_*()宏,因?yàn)樗麄儠?huì)打印出結(jié)果的比較,但以及兩個(gè)操作數(shù)不只。
參數(shù)總是進(jìn)行一次評(píng)估。因此,它是有副作用的參數(shù)確定。然而,與任何普通的 C/c + + 函數(shù),一樣的參數(shù)的計(jì)算順序是未定義 (即編譯器是自由選擇任何順序) 和您的代碼不應(yīng)依賴于任何特定的參數(shù)計(jì)算順序。
ASSERT_EQ()沒有指針的指針平等。如果使用兩個(gè) C 字符串,它測(cè)試如果它們?cè)谙嗤膬?nèi)存位置,如果它們具有相同的值。因此,如果您想通過(guò)值比較 C 字符串 (例如const char *),使用ASSERT_STREQ() ,將在稍后介紹的。特別是,聲稱是 C 字符串為空,使用ASSERT_STREQ NULL c_string) 。不過(guò),若要比較兩個(gè)字符串對(duì)象,您應(yīng)使用ASSERT_EQ.
這一節(jié)中的宏 (字符串和wstring這兩個(gè)狹窄和寬字符串對(duì)象的工作).
可用性: Linux、 Windows、 mac。
字符串比較
在此組中的斷言,比較兩個(gè)C 字符串。如果要比較兩個(gè)字符串對(duì)象,請(qǐng)使用EXPECT_EQ、 EXPECT_NE、 等代替。
致命的斷言 | 非致命的斷言 | 驗(yàn)證 |
ASSERT_STREQ (, expected_str actual_str); | EXPECT_STREQ (, expected_str actual_str); | 兩個(gè) C 字符串具有相同的內(nèi)容 |
ASSERT_STRNE (, str1 str2); | EXPECT_STRNE (, str1 str2); | 兩個(gè) C 字符串具有不同的內(nèi)容 |
ASSERT_STRCASEEQ (, expected_stractual_str); | EXPECT_STRCASEEQ (, expected_stractual_str); | 兩個(gè) C 字符串具有相同的內(nèi)容,忽略案例 |
ASSERT_STRCASENE (, str1 str2); | EXPECT_STRCASENE (, str1 str2); | 兩個(gè) C 字符串具有不同的內(nèi)容,忽略案例 |
請(qǐng)注意斷言名稱中的"案例"意味著忽略大小寫。
* STREQ *和* STRNE *也接受寬的 C 字符串 (wchar_t *)。如果兩個(gè)寬字符串比較失敗,其值將打印為 UTF 8 窄字符串。
一個(gè)空字符串和NULL指針被視為不同.
可用性: Linux、 Windows、 mac。
另請(qǐng)參閱: 更多的字符串比較特技 (子串、 前綴、 后綴,和正則表達(dá)式匹配,例如),請(qǐng)參見高級(jí)谷歌測(cè)試指南.
簡(jiǎn)單的測(cè)試
要?jiǎng)?chuàng)建一個(gè)測(cè)試:
- 使用TEST()宏來(lái)定義和測(cè)試函數(shù)命名,這些都是普通的 c + + 函數(shù)不會(huì)返回一個(gè)值。
- 在此函數(shù)中,與您要包括的任何有效的 c + + 語(yǔ)句一起使用各種谷歌測(cè)試斷言檢查值。
- 確定測(cè)試的結(jié)果,斷言 ;如果在測(cè)試中的任何斷言失敗 (致命或非致命),或如果測(cè)試崩潰,整個(gè)測(cè)試失敗。否則,它會(huì)成功。
TEST(test_case_name, test_name) {
... test body ...
}
TEST()參數(shù)從一般轉(zhuǎn)到特定。第一個(gè)參數(shù)是測(cè)試用例的名稱,第二個(gè)參數(shù)是內(nèi)測(cè)試用例的測(cè)試的名稱。這兩個(gè)名稱必須是有效的 c + + 標(biāo)識(shí)符,它們不應(yīng)包含下劃線 (_)。測(cè)試的完整名稱由其包含測(cè)試用例和其個(gè)人名稱組成。來(lái)自不同測(cè)試用例的測(cè)試可以有個(gè)別的名稱相同。
例如,讓我們看一個(gè)簡(jiǎn)單的整數(shù)函數(shù):
int Factorial(int n); // Returns the factorial of n
此函數(shù)的測(cè)試用例可能類似于:
// Tests factorial of 0.
TEST(FactorialTest, HandlesZeroInput) {
EXPECT_EQ(1, Factorial(0));
}
// Tests factorial of positive numbers.
TEST(FactorialTest, HandlesPositiveInput) {
EXPECT_EQ(1, Factorial(1));
EXPECT_EQ(2, Factorial(2));
EXPECT_EQ(6, Factorial(3));
EXPECT_EQ(40320, Factorial(8));
}
谷歌測(cè)試組的測(cè)試結(jié)果的測(cè)試用例,所以邏輯上相關(guān)的測(cè)試應(yīng)在同一測(cè)試用例 ;換句話說(shuō),他們TEST()的第一個(gè)參數(shù)應(yīng)是相同的。在上面的示例中,我們有兩個(gè)測(cè)試, HandlesZeroInput和HandlesPositiveInput,屬于同一個(gè)測(cè)試用例FactorialTest.
可用性: Linux、 Windows、 mac。
測(cè)試夾具: 使用相同的數(shù)據(jù)配置多個(gè)測(cè)試
如果您發(fā)現(xiàn)自己相似的數(shù)據(jù)寫入兩個(gè)或更多的測(cè)試操作,您可以使用測(cè)試夾具。這樣,您就可以重復(fù)使用的對(duì)象的多個(gè)不同測(cè)試相同的配置。
若要?jiǎng)?chuàng)建夾具,只是:
- 派生類從:: testing::Test 。啟動(dòng)其體保護(hù):或公共: ,我們要從子類訪問夾具成員。
- 在類中聲明您計(jì)劃使用的任何對(duì)象。
- 如有必要,寫了默認(rèn)的構(gòu)造函數(shù)或SetUp()函數(shù),準(zhǔn)備每個(gè)測(cè)試的對(duì)象。一個(gè)常見的錯(cuò)誤是,用一個(gè)小u - Setup()不要讓發(fā)生在你身上的拼寫SetUp() 。
- 如有必要,寫了析構(gòu)函數(shù)或TearDown()函數(shù)釋放您在SetUp()中分配的任何資源。要了解何時(shí)應(yīng)使用析構(gòu)函數(shù)構(gòu)造函數(shù)和何時(shí)應(yīng)使用SetUp()/TearDown(),請(qǐng)閱讀此FAQ 條目.
- 如果需要,定義您要共享的測(cè)試的子例程。
使用時(shí)夾具,使用TEST_F()的TEST()而不是因?yàn)樗试S您訪問對(duì)象和測(cè)試夾具的子例程:
TEST_F(test_case_name, test_name) {
... test body ...
}
像TEST(),第一個(gè)參數(shù)是測(cè)試用例的名稱,但對(duì)于TEST_F() ,這必須測(cè)試夾具類的名稱。您可能已經(jīng)猜到: _F是夾具。
不幸的是,在 c + + 宏系統(tǒng)不允許我們能夠創(chuàng)建一個(gè)單一的宏,可以處理這兩種類型的測(cè)試。使用錯(cuò)誤的宏將導(dǎo)致編譯器錯(cuò)誤。
此外,在TEST_F()中,在使用之前必須首先定義測(cè)試夾具類,否則你會(huì)編譯器錯(cuò)誤"' 虛擬類聲明外'"。
用TEST_F()定義的每個(gè)測(cè)試中,Google 測(cè)試將:
- 在運(yùn)行時(shí)創(chuàng)建新的測(cè)試夾具
- 立即將其初始化通過(guò)SetUp() ,
- 運(yùn)行測(cè)試
- 通過(guò)調(diào)用TearDown()清理
- 刪除測(cè)試夾具。請(qǐng)注意不同的測(cè)試,在同一個(gè)測(cè)試用例中有不同的測(cè)試夾具對(duì)象,創(chuàng)建下一個(gè)之前,谷歌測(cè)試總是刪除測(cè)試夾具。谷歌測(cè)試不會(huì)重用相同的測(cè)試夾具,為多個(gè)測(cè)試。一個(gè)測(cè)試使夾具的任何更改不會(huì)影響其他測(cè)試。
作為一個(gè)例子,讓我們寫測(cè)試 FIFO 隊(duì)列類命名隊(duì)列中,具有以下接口:
template <typename E> // E is the element type.
class Queue {
public:
Queue();
void Enqueue(const E& element);
E* Dequeue(); // Returns NULL if the queue is empty.
size_t size() const;
...
};
首先,定義夾具的類。按照約定,,你應(yīng)該給它生成器美孚在哪里類名稱正在進(jìn)行測(cè)試。
class QueueTest : public ::testing::Test {
protected:
virtual void SetUp() {
q1_.Enqueue(1);
q2_.Enqueue(2);
q2_.Enqueue(3);
}
// virtual void TearDown() {}
Queue<int> q0_;
Queue<int> q1_;
Queue<int> q2_;
};
在這種情況下,由于我們不需要每個(gè)測(cè)試,除已做的析構(gòu)函數(shù)之后進(jìn)行清理,則不需要TearDown() 。
現(xiàn)在我們會(huì)編寫測(cè)試使用TEST_F()和這種裝置。
TEST_F(QueueTest, IsEmptyInitially) {
EXPECT_EQ(0, q0_.size());
}
TEST_F(QueueTest, DequeueWorks) {
int* n = q0_.Dequeue();
EXPECT_EQ(NULL, n);
n = q1_.Dequeue();
ASSERT_TRUE(n != NULL);
EXPECT_EQ(1, *n);
EXPECT_EQ(0, q1_.size());
delete n;
n = q2_.Dequeue();
ASSERT_TRUE(n != NULL);
EXPECT_EQ(2, *n);
EXPECT_EQ(1, q2_.size());
delete n;
}
上述使用了ASSERT_ *和EXPECT_ *斷言。經(jīng)驗(yàn)法則是使用EXPECT_ *當(dāng)您想要繼續(xù)斷言失敗后,透露更多的錯(cuò)誤,并使用ASSERT_ *時(shí)繼續(xù)后失敗沒什么意義的測(cè)試。例如,出列測(cè)試中的第二個(gè)說(shuō)法是ASSERT_TRUE (n! = NULL),就像我們要取消引用指針n后,這將導(dǎo)致 segfault n為NULL時(shí).
當(dāng)這些測(cè)試運(yùn)行時(shí),會(huì)發(fā)生下列情況:
- 谷歌測(cè)試構(gòu)造讓 (我們稱之為t1 QueueTest對(duì)象 ).
- t1。SetUp()初始化t1 .
- T1上 ( IsEmptyInitially ) 的第一個(gè)測(cè)試運(yùn)行 .
- t1。TearDown()測(cè)試完成后清理。
- t1被破壞。
- 這次運(yùn)行的DequeueWorks測(cè)試上另一個(gè)QueueTest對(duì)象,重復(fù)上述步驟。
可用性: Linux、 Windows、 mac。
注: 谷歌測(cè)試自動(dòng)保存所有谷歌測(cè)試標(biāo)志時(shí)測(cè)試對(duì)象構(gòu)造,并還原它們時(shí)它破壞。
調(diào)用測(cè)試
TEST()和TEST_F()隱式使用谷歌測(cè)試注冊(cè)他們的測(cè)試。所以,不同于與很多其他 c + + 測(cè)試框架,你不必為了運(yùn)行它們 re-list 定義的所有測(cè)試。
定義您的測(cè)試之后, 您可以運(yùn)行它們的RUN_ALL_TESTS() ,它返回0 ,如果所有的測(cè)試都成功或1否則。請(qǐng)注意RUN_ALL_TESTS()運(yùn)行您的鏈接單元中的所有測(cè)試— — 它們可以從不同的測(cè)試案例或甚至不同的源文件。
當(dāng)調(diào)用, RUN_ALL_TESTS()宏:
- 保存所有谷歌測(cè)試標(biāo)志的狀態(tài)。
- 創(chuàng)建第一個(gè)測(cè)試夾具對(duì)象。
- 初始化它通過(guò)SetUp().
- 夾具對(duì)象上運(yùn)行測(cè)試。
- 通過(guò)TearDown()的夾具清理.
- 刪除夾具。
- 恢復(fù)所有谷歌測(cè)試標(biāo)志的狀態(tài)。
- 接下來(lái)的測(cè)試,重復(fù)上述步驟,直到所有的測(cè)試運(yùn)行。
此外,如果文本夾具的構(gòu)造函數(shù)生成致命故障在步驟 2 中,是沒有意義的步驟 3-5,因此被跳過(guò)。同樣,如果第 3 步生成一個(gè)致命的失敗,則將被跳過(guò)第 4 步。
重要提示: 您一定不能忽略的返回值RUN_ALL_TESTS(),或?qū)⒔o你gcc編譯器錯(cuò)誤。這種設(shè)計(jì)的理由是自動(dòng)化測(cè)試服務(wù)確定是否對(duì)其退出代碼,不是在它的標(biāo)準(zhǔn)輸出/stderr 輸出 ; 測(cè)試已通過(guò)基于因此你的main ()函數(shù)必須返回值的RUN_ALL_TESTS().
此外,您應(yīng)調(diào)用RUN_ALL_TESTS()唯一一次。叫它不止一次沖突與一些高級(jí)功能 (如線程安全死亡測(cè)試) 的谷歌測(cè)試,因此不支持。
可用性: Linux、 Windows、 mac。
編寫函數(shù) main)
您可以從這個(gè)樣板啟動(dòng):
#include "this/package/foo.h"
#include "gtest/gtest.h"
namespace {
// The fixture for testing class Foo.
class FooTest : public ::testing::Test {
protected:
// You can remove any or all of the following functions if its body
// is empty.
FooTest() {
// You can do set-up work for each test here.
}
virtual ~FooTest() {
// You can do clean-up work that doesn't throw exceptions here.
}
// If the constructor and destructor are not enough for setting up
// and cleaning up each test, you can define the following methods:
virtual void SetUp() {
// Code here will be called immediately after the constructor (right
// before each test).
}
virtual void TearDown() {
// Code here will be called immediately after each test (right
// before the destructor).
}
// Objects declared here can be used by all tests in the test case for Foo.
};
// Tests that the Foo::Bar() method does Abc.
TEST_F(FooTest, MethodBarDoesAbc) {
const string input_filepath = "this/package/testdata/myinputfile.dat";
const string output_filepath = "this/package/testdata/myoutputfile.dat";
Foo f;
EXPECT_EQ(0, f.Bar(input_filepath, output_filepath));
}
// Tests that Foo does Xyz.
TEST_F(FooTest, DoesXyz) {
// Exercises the Xyz feature of Foo.
}
} // namespace
int main(int argc, char **argv) {
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}
:: Testing::InitGoogleTest()函數(shù)解析命令行,因?yàn)楣雀铚y(cè)試標(biāo)志,并刪除所有認(rèn)可的標(biāo)志。這允許用戶控制通過(guò)各種標(biāo)志,我們將介紹在AdvancedGuide的測(cè)試程序的行為。您必須在調(diào)用RUN_ALL_TESTS()之前, 調(diào)用此函數(shù)或標(biāo)志不會(huì)被正確初始化。
在 Windows 上, InitGoogleTest()同樣適用于寬字符串,因此它可以用于UNICODE模式以及在編譯的程序。
但也許你認(rèn)為編寫所有那些 main () 函數(shù)是太多的工作嗎?我們完全同意你,這就是為什么 Google 測(cè)試提供 main () 的基本實(shí)現(xiàn)。如果它適合您的需要,然后只是鏈接您的測(cè)試與 gtest_main 庫(kù),你是要走好。
對(duì)于 Visual c + + 用戶的重要說(shuō)明
如果你把你的測(cè)試放在圖書館,你的main ()函數(shù)是在另一個(gè)庫(kù)或.exe 文件中將不會(huì)運(yùn)行這些測(cè)試。原因是 Visual c + + 中的bug 。當(dāng)您定義您的測(cè)試時(shí),谷歌測(cè)試創(chuàng)建某些注冊(cè)他們的靜態(tài)對(duì)象。這些對(duì)象不從其他地方引用,但仍然應(yīng)該運(yùn)行它們的構(gòu)造函數(shù)。Visual c + + 鏈接器看到什么庫(kù)中引用的其他地方時(shí)它會(huì)引發(fā)圖書館。你要從主程序從丟棄它保持鏈接器的測(cè)試引用您的庫(kù)。這里是如何做這件事。某處代碼庫(kù)中聲明的函數(shù):
__declspec(dllexport) int PullInMyLibrary() { return 0; }
如果你把你的測(cè)試放在靜態(tài)庫(kù) (而不是 DLL) 然后__declspec(dllexport)則不需要。現(xiàn)在,在 main 程序中寫一段代碼,它調(diào)用該函數(shù):
int PullInMyLibrary();
static int dummy = PullInMyLibrary();
這會(huì)讓你的測(cè)試引用,會(huì)使他們自行注冊(cè)在啟動(dòng)時(shí)。
此外,如果您在靜態(tài)庫(kù)中定義您的測(cè)試,添加/OPT:NOREF主程序鏈接器選項(xiàng)。如果您使用 MSVC + + IDE,轉(zhuǎn)到您的.exe 項(xiàng)目屬性/配置屬性/鏈接器/優(yōu)化和設(shè)置的引用設(shè)置為保持未引用數(shù)據(jù) (/ 選擇: NOREF)。這將使 Visual c + + 鏈接器丟棄單個(gè)符號(hào)生成最終的可執(zhí)行文件從您的測(cè)試。
不過(guò)還有一個(gè)更多陷阱。如果您使用谷歌測(cè)試靜態(tài)庫(kù) (即如何定義的 gtest.vcproj) 作為您的測(cè)試也必須位于一個(gè)靜態(tài)庫(kù)。如果你要讓他們?cè)?DLL 中,您必須更改將建成一個(gè) DLL 以及谷歌測(cè)試。否則為你的測(cè)試將不會(huì)正確運(yùn)行,或者將不能運(yùn)行。普遍的結(jié)論是: 使您的生活更輕松 — — 圖書館不寫你的測(cè)試 !
從這里去哪里
恭喜 !您已經(jīng)了解谷歌測(cè)試基礎(chǔ)。可以開始編寫和測(cè)試運(yùn)行谷歌測(cè)試、 閱讀一些樣本,或繼續(xù)AdvancedGuide,它描述了許多更有用的谷歌測(cè)試功能。
已知的局限性
谷歌測(cè)試被為了是線程安全的。執(zhí)行是線程安全的pthreads圖書館在哪里可用的系統(tǒng)上。它目前是不安全使用谷歌測(cè)試斷言從兩個(gè)線程同時(shí)在其他系統(tǒng) (如 Windows)。在大多數(shù)的測(cè)試中這不是問題,通常所斷言的事,主線程。如果你想幫助,您可以在您的平臺(tái)gtest port.h執(zhí)行必要的同步基元志愿者。