做單元測試,一般是驗證函數輸出數據與預期是否相符。但是也有例外,我們可能需要驗證函數在接收到非法參數時是否會斷言或拋異常,例如下面這個例子:
int foo(int *p)
{
assert(p != nullptr);
return *p;
}
當傳給foo
的實參爲nullptr
時,運行的預期結果就是斷言後進程異常退出。這在單元測試中如何驗證呢?如何不讓這些驗證異常值的用例干擾單元測試的工作流呢?
googletest提供了三組宏分別用於測試導致進程崩潰、導致進程退出、拋異常的函數,他們分別是EXPECT_DEATH
、EXPECT_EXIT
、EXPECT_THROW
及其各自的ASSERT版本。使用這些宏測試相應的函數不會干擾單元測試的工作流,換言之,函數斷言並不會導致單元測試進程異常退出。而如果使用一般的宏,例如EXPECT_EQ
,來驗證傳入異常值時函數是否會斷言時,單元測試進程也會異常退出,無法執行後續的測試用例。
以使用EXPECT_DEATH
宏測試foo
函數爲例,測試用例需要這麼寫:
TEST(foo, death)
{
EXPECT_DEATH(foo(nullptr), ".*");
}
EXPECT_DEATH
,接受兩個參數,分別是要測試的語句和要匹配的錯誤信息的正則表達式,這裏我們並不關心實際的錯誤信息,所以直接傳入".*"匹配任意信息。如果錯誤信息匹配不上的話,這個測試用例還是會被認爲失敗。
EXPECT_DEATH
的基本原理就是在執行測試語句前fork
一個進程出來執行,這樣這個進程的死活就不會干擾單元測試進程本體了。
宏的手冊以及更詳細的原理,請查看googletest官方文檔。