C++ 測試

C++單元測試工具,現在市面上有很多並且不少都是免費開源的,這次要介紹的是gmock,來自大名鼎鼎的Google,gmock是包含了gtest的一個單元測試框架,在gtest基礎上增加了許多便於開發人員進行mock打樁的接口等,可以理解爲gtest負責進行測試,gmock負責測試前的打樁,gmock比起其他的cppunit等測試工具來說,最大的優點就是可以有簡單的內置宏來定義一個類的mock類進行打樁,這爲C++類單元測試帶來了極大的便利。

【編譯gmock】

解壓縮gmock-1.7.0.zip,將解壓後的文件上傳至linux服務器。

cd進入gmock-1.7.0/make目錄,輸入make直接編譯,完成後在make目錄下執行./gmock_test,打印如下內容,則說明編譯成功:

之後再次執行make gmock.a命令生成gmock靜態庫(內含gtest),會在make目錄下變成生成gmock.a,將gmock.a文件更名爲libgmock.a後拷貝到自己環境的庫目錄中之後就可以在自己的單元測試工程的make文件中通過添加-lgmock參數來連接gmock了。

【使用gmock】

介紹一個簡單的例子:

現有Foo.h和Foo.cpp兩個文件,文件內容如下:

現在要對Foo函數進行單元測試。

在Foo.cpp相同目錄下新建一個Foo_test.cpp文件,文件內容如下:

這裏有兩個宏TEST和EXPECT_EQ, TEST這個宏,它有兩個參數,這兩個參數的解釋爲:[TestSuiteName,TestCaseName],測試套間名,測試用例名。

爲本次測試新建一個makefile,內容如下:

執行make test編譯,編譯成功後,./test執行測試。

【Gmock中的斷言】

在上一節的示例中,可以看到EXPECT_EQ來檢查函數返回結果已確定用例是否測試通過,這個EXPECT_EQ就是一種斷言宏,在gmock/gtest中,斷言的宏可以理解爲分爲兩類,一類是ASSERT系列,一類是EXPECT系列。

一個直觀的解釋就是:

▪ ASSERT_* 系列的斷言,當檢查點失敗時,退出當前函數(注意:並非退出當前案例)。

▪ EXPECT_* 系列的斷言,當檢查點失敗時,繼續往下執行。

以上兩種斷言類型下根據比較的數據類型又進一步:

布爾數據檢查

數值型數據檢查

字符串類型檢查

異常檢查

浮點型檢查

【Gmock打樁並測試】

在C++項目中,會有大量接口類方法的調用,下面就介紹一個簡單的對抽象接口類進行mock打樁測試的例子,在這個例子中我們有一個interface.h裏面定義瞭如下接口類:

新建一個inteface_mock.cpp文件

注:在實際使用時,應當將基類中的所有純虛函數進行打樁,否則會編譯報錯。

▲幾個宏的說明:MOCK_METHOD#1(#2, #3(#4) )

#1表示你要mock的方法共有幾個參數

#2是你要mock的方法名稱

#3表示這個方法的返回值類型

#4是這個方法具體的參數

以上就已經完成了對接口類的mock,但打樁的工作還沒有全部完成,還需要設置某個成員函數執行時能按我們的期望來返回值,我們繼續往下看。

選擇一個要進行單元測試的文件s_ls_dosomething.cpp,裏面只有一個函數:

再新建一個s_ls_dosomething_ut.cpp作爲s_ls_dosomething.cpp這個文件中函數單元測試文件,內容如下:

之前在完成interface_mock.cpp的時候說打樁還沒有全部完成,剩下的工作就在這個TEST中了,就是通過ON_CALL/ EXPECT_CALL來設定樁函數的返回值,這2個宏的具體說明如下:

ON_CALL(#1, #2(#3)).WillByDefault(Return(#4));

#1表示mock對象

#2表示想定義的那個方法名稱。

#3表示定義方法的參數,只有當傳入的參數=#3的值時,纔會生效,也可用_,表示匹配任何參數輸入都生效

#4表示調用要返回值。

除了ON_CALL以外,還有EXPECT_CALL(#1, #2(#3)),參數含義同ON_CALL,還可以有額外的功能,比如:

EXPECT_CALL(#1, #2(#3)).Times(5).WillOnce(Return(100))

.WillOnce(Return(150))

.WillRepeatedly(Return(200));

表示第一次返回100,第二次調用返回150,後面全部返回200,以此類推。

ON_CALL和EXCEPT_CALL相當於設置樁函數的屬性設置,因此應當在樁函數調用前進行設置。除了TEST宏函數定義和main函數之外,在例子中可以看到我還定義了SubServiceCall,由於這個函數會向Fbase發送服務調用請求,但我們用MockF2Pack打的包其實是空無一物,調用服務顯然會使測試過程不可控,因此我們把這個函數也進行打樁。

到這裏,打樁和單元測試用例編寫工作算是完成了,編譯並生成一個單元測試的可執行文件,然後執行,就完成了一個文件的單元測試工作。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章