這一節,我們來看Gtest的FAQ(Frequently-Asked Questions)。
為什麼測試案例和測試執行個體命名中不應包含底線
在C++中,對於以下情況,相應的標識可能會被編譯器或標準庫使用:
- 以底線開始並緊接一個大寫字母的標識
- 包含連續兩個底線的標識
為避免標識符衝突,使用者代碼中不應自訂以上兩種情況的標識。使用TEST()或TEST_F()時,濫用底線,將有可能產生標誌符命名衝突。
當我們定義以下測試執行個體並執行測試程式時,Gtest會為我們產生一個名為TestCaseName_TestName_Test的類。
TEST(TestCaseName, TestName)
如果TestCaseName或TestName中包含底線,情況會怎樣呢?
- TestCaseName以"_"開頭(例如_Foo),我們得到_Foo_TestName_Test
- TestCaseName以"_"結尾(例如Foo_),我們得到Foo__TestName_Test
- TestName以"_"開頭(例如_bar),我們得到TestCaseName__bar_Test
- TestName以"_"結尾(例如bar_),我們得到TestCaseName_bar__Test
以上命名方式都有可能產生命名衝突,因而TestCaseName和TestName以“_"開頭或結尾均不可取。
如果TestCaseName或TestName命名中包含底線,情況又會怎樣呢?
TEST(Time, Flies_Like_An_Arrow) { ... }
TEST(Time_Flies, Like_An_Arrow) { ... }
假設我們同時定義了兩個測試執行個體,Oops! 這時Gtest將產生同一個類:Time_Flies_Like_An_Arrow。
因而為避免命名衝突的情況發生(不管是與系統標誌衝突或自訂的標誌間衝突),我們的測試案例或測試執行個體的命名最好不包含底線。當然,這是建議而不是必須的。
在測試韌體類中,為什麼要用set-up/tear-down函數,而不使用建構函式/解構函式
還記得測試韌體的作用嗎?通過測試韌體,Gtest為每一個測試執行個體產生一個測試韌體對象,該對象為每個測試執行個體提供獨立的資料配置,通過編寫SetUp()/TearDown()函數,我們可以對資料進行初始化和銷毀操作。
對於一個類而言,建構函式和解構函式不是同樣有初始化資料/銷毀資料的作用嗎?Gtest提供SetUp()和TearDown()豈不是多此一舉?No,no,no, 對於以下情況,還非得用SetUp()/TearDown()不可:
對於銷毀操作中包含異常拋出調用的,由於在C++的解構函式中不能拋出異常,這時候需使用TearDown()調用(關於C++解構函式拋出異常的介紹,請看這裡)。
為什麼當我調用RUN_ALL_TESTS()函數時,編譯器拋出"ignoring return value"警告
一些Gtest使用者忽略了RUN_ALL_TESTS()的傳回值,理應這樣調用:
return RUN_ALL_TESTS();
而不是這樣:
RUN_ALL_TESTS();
測試程式根據RUN_ALL_TESTS()的傳回值判斷其所包含的測試執行個體是否通過。如果在main()函數中忽略其傳回值,即使是某個測試執行個體檢測失敗,整個測試程式也會被認為是無檢測失敗地成功執行。
為避免誤用RUN_ALL_TESTS(),對於不作為main()傳回值的調用,gcc將對此拋出警告,為消除該警告,將RUN_ALL_TESTS()作為main()函數的傳回值即可。
如何為一個測試韌體定義多個測試案例
我想編寫多個測試執行個體,它們對應於同一個測試韌體,對此,是否要為每一個測試執行個體編寫新的測試韌體類?就像這樣:
class FooTest : public BaseTest {};
TEST_F(FooTest, Abc) { ... }
TEST_F(FooTest, Def) { ... }
class BarTest : public BaseTest {};
TEST_F(BarTest, Abc) { ... }
TEST_F(BarTest, Def) { ... }
這裡類FooTest和類BarTest什麼都不做,我們這樣定義只是為了產生兩個不同的測試案例名。
其實使用typedef能更便捷地達到目的:
typedef BaseTest FooTest;
TEST_F(FooTest, Abc) { ... }
TEST_F(FooTest, Def) { ... }
typedef BaseTest BarTest;
TEST_F(BarTest, Abc) { ... }
TEST_F(BarTest, Def) { ... }
關於Gtest的更多FAQ,請參看這裡。