引言
在《Google C++單元測試架構(Gtest)系列教程之一——入門》中,介紹了如何編譯測試代碼、產生可執行檔,下面我們來看Gtest提供了哪些語句和架構來方便我們編寫單元測試代碼。
斷言
1.斷言類型
斷言即判斷一個條件是否為真的語句,它是構成Gtest測試代碼最基本的單元。Gtest為我們提供了兩種類型的斷言:
- ASSERT_*系列,當檢查點失敗時,終止測試函數;
- EXPECT_*系列,當檢查點失敗時,不終止所在測試函數,繼續往下執行。
我們使用Assert 陳述式的時候,一般選擇EXPECT_*系列的,基於以下兩個原因:
- 該系列宣告失敗的時候並不終止所在測試函數,該函數中後續的檢查點還能得到執行;
- 測試函數中可能包含有記憶體申請和釋放的調用,ASSERT_*系列斷言可導致後續的記憶體釋放調用得不到執行,帶來記憶體流失問題。
2.執行個體
當一個斷言判斷失敗的時候,Gtest將列印出該斷言所在的源檔案和行號,並給出失敗的資訊。我們來看一個布爾值檢查的例子:
// IsPrime(int)函數判斷入參是否為質數
EXPECT_FALSE(IsPrime(1));
// ...
假如IsPrime(int)函數實現有誤,將1也當成質數的話,測試的運行結果會包含如下提示:
my_test.cc:15: Failure
Value of: IsPrime(1)
Actual: true
Expected: false
Gtest為我們提供了布爾值檢查、數值型資料檢查、字串檢查等多種檢查類型,關於這些檢查類型更詳細的使用方法,可以參看這裡,還有這裡。
測試函數
1.TEST()
在Gtest中,我們使用宏TEST()來定義我們的測試函數,使用的方式如下:
TEST(test_case_name, test_name) {
... test body ...
}
其中test body可以包含任何合法的C++語句以及上面提到的Assert 陳述式。
TEST()的第一個參數即測試案例的名稱,第二個參數為該測試案例中測試執行個體的名稱。兩個參數的命名字元必須為C++的合法標誌符,並且不能含有底線“_"。一個測試的全稱由測試案例名稱和測試執行個體名稱組成。
2.執行個體
光說,大家可能難以理解TEST()的使用方法以及test_case_name和test_name的區別,下面我們來看一個使用TEST()的執行個體。
int Factorial(int n); // Returns the factorial of n
假設Factorial(int n)為我們的被測函數,它的功能是返回n的階乘即n!,測試函數如下:
// 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));
}
FactorialTest為我們測試案例的名稱,當然測試案例的名稱不一定為XXXTest,只要能說明被測對象即可;HandlesZeroInput和HandlePositiveInput為測試執行個體的名稱,這兩個執行個體同屬FactorialTest測試案例,可以任意設定測試執行個體的名稱,但以能體現測試功能的命名方式為佳。
編譯測試代碼並執行程式,執行結果如下:
Running main() from gtest_main.cc
[==========] Running 2 tests from 1 test case.
[----------] Global test environment set-up.
[----------] 2 tests from FactorialTest
[ RUN ] FactorialTest.HandlesZeroInput
[ OK ] FactorialTest.HandlesZeroInput (0 ms)
[ RUN ] FactorialTest.HandlesPositiveInput
[ OK ] FactorialTest.HandlesPositiveInput (0 ms)
[----------] 2 tests from FactorialTest (1 ms total)
[----------] Global test environment tear-down
[==========] 2 tests from 1 test case ran. (1 ms total)
[ PASSED ] 2 tests.
可以看出Gtest以測試案例(TestCase)為單位輸出測試結果,在一個測試案例中,列出了其包含的測試執行個體(Tests),“測試案例名.測試執行個體名"為一個測試(Test)的全稱,例如FactorialTest.HandlesZeroInput。
小結
本文介紹了Gtest的斷言和TEST()方法,斷言是構成Gtest測試代碼的基本語句;TEST()可用於函數測試,測試案例(TestCase)可包含多個測試執行個體(Tests),這種階層方便我們對某個測試對象的多個測試執行個體進行管理。下一節將介紹測試韌體(Test fixture),看看Gtest還給我們提供了哪些方法,方便我們進行測試案例的編碼和管理:)
Reference: googletest project
《玩轉Google開源C++單元測試架構Google Test系列(gtest)》by CoderZh