C++測試利器--google test開源測試框架

資料html

  偶然發現了google的測試框架gtest,立刻試了下,效果挺不錯,特別是對於寫c++的人來講,方便不少。之前本身寫c++的模塊,一般是寫好了模塊後再另外定義些函數,而後在函數裏面寫測試用例來測試模塊,若是測試點比較多,光是定義測試函數都要花費很多時間。gtest至關於大大節省了這個過程,用起來很是簡單,直接用宏來定義測試用例,而且有不少豐富的宏來輔助測試,例如斷言、預測值、死亡測試等。java

  廢話很少說,先上gtest的一些資料:linux

gtest的代碼託管地址:https://github.com/google/googletest,用git clone下來就能夠了。c++

使用gtest構建測試用例指導:https://github.com/google/googletest/tree/master/googletestgit

gtest英文文檔:https://github.com/google/googletest/blob/master/googletest/docs/Documentation.mdgithub

gtest中文博客:玩轉Google開源C++單元測試框架Google Test系列,這系列博客對gtest的具體使用講解的很是詳細。框架

gmock使用文檔:https://github.com/google/googletest/blob/master/googlemock/docs/Documentation.md函數

gmock中文文檔:Google Mock啓蒙篇單元測試

  gtest項目中包含了兩個框架,一個gtest測試框架,一個是gmock框架。gtest相似於java裏面的junit,用來作單元測試的;gmock主要是用來mock待測試模塊依賴的一些對象,幫助你在測試中去除沒必要要的依賴,相似與java的jMockEasyMock測試

好了,接下來直接上例子吧(注:下面的例子都是在linux下編譯運行的,若是要在Windows上,須要看看gtest的文檔)。

gtest demo

  clone下來gtest後,能夠在googletest目錄中找到make目錄:

,make目錄中的Makefile是gtest幫咱們寫好的一個使用gtest測試框架來測試模塊的例子。咱們只須要把這個文件拷貝到寫測試模塊代碼的目錄,再改下面幾個地方就能夠編譯運行測試模塊。

 1 GTEST_DIR = .. #設置gtest的項目目錄
 2 
 3 USER_DIR = ../samples #設置測試代碼所在的目錄
 4 
 5 CPPFLAGS += -isystem $(GTEST_DIR)/include #設置預處理器參數
 6 
 7 CXXFLAGS += -g -Wall -Wextra -pthread #設置編譯器參數
 8 
 9 TESTS = sample1_unittest #設置編譯目標
10 
11 。。。
12 
13 #下面的目標生成規則改爲測試模塊的
14 
15 sample1.o : $(USER_DIR)/sample1.cc $(USER_DIR)/sample1.h $(GTEST_HEADERS)
16 
17 $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1.cc
18 
19 sample1_unittest.o : $(USER_DIR)/sample1_unittest.cc \
20 
21 $(USER_DIR)/sample1.h $(GTEST_HEADERS)
22 
23 $(CXX) $(CPPFLAGS) $(CXXFLAGS) -c $(USER_DIR)/sample1_unittest.cc
24 
25 sample1_unittest : sample1.o sample1_unittest.o gtest_main.a
26 
27 $(CXX) $(CPPFLAGS) $(CXXFLAGS) -lpthread $^ -o $@

  上面都是make腳本的語法,不清楚的能夠先Google下。好了,一塊兒準備就緒後,來看看一個簡單的例子。首先,先寫個要測試的函數:

1 bool IsEven(int n) {
2     return (n % 2) == 0;
3 }

  這是一個判斷一個數是否爲偶數的函數,是否是很是的簡單~~下面咱們就來編寫一個簡單的測試案例:

1 TEST(IsEvenTest, EqTest)
2 {
3     EXPECT_FALSE(IsEven(1));
4     EXPECT_TRUE(IsEven(2));
5 }

  上面能夠看到,編寫一個測試案例是多麼的簡單。咱們使用了TEST這個宏,它有兩個參數,這兩個參數的定義是:[TestSuiteName,TestCaseName],個人理解是TestSuiteName是對某個模塊總案例名,TestCaseName是這個案例中某個case的名字。

  對檢查點的檢查,咱們上面使用到了EXPECT_FLASE和EXPECT_TRUE這兩個宏,這兩個宏主要分別用來判斷函數返回值是否爲false和true。Google還包裝了一系列EXPECT_* 和ASSERT_*的宏,而EXPECT系列和ASSERT系列的區別是:

1. EXPECT_* 失敗時,案例繼續往下執行。

2. ASSERT_* 失敗時,直接在當前函數中返回,當前函數中ASSERT_*後面的語句將不會執行。

  至於其它具體宏的介紹,能夠經過上面給出的連接來查看。

  好了,一塊兒都準備好了,運行的結果是全部的測試都經過。

  若是咱們把第一個EXPECT_FALSE改成EXPECT_TRUE的結果呢?答案是測試是失敗的,並且會給出具體出錯在文件中的哪一行,以及出錯的緣由。

  這是個很簡單的使用gtest的例子,雖然簡單,但基本涵蓋了使用gtest的流程,並且用這些基本的功能就能解決大部分問題了。至於gtes的一些高級功能,須要的時候能夠查上面連接中的文檔。

gmock demo

  編譯運行的方式和gtest相似,Makefile文件在googlemock目錄中的make目錄中,按前面相似的修改這個Makefile文件就行。如今要測試的模塊以下:

1 void func(FooInterface *p)
2 {
3     p->DoThis();
4 }

  這個模塊依賴於實現了抽象類FooInterface的對象,FooInterface類定義以下:

1 class FooInterface {
2 public:
3     virtual ~FooInterface() {}
4     virtual void DoThis() = 0;
5 };

  如今咱們須要mock這個抽象類,gmock經過下面的宏來實現:

1 class MockFoo : public FooInterface {
2 public:
3     MockFoo() {}
4     MOCK_METHOD0(DoThis, void());
5 private:
6     GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo);
7 };
 

  MOCK_METHOD*是一個宏,用來mock父類中的虛函數,*表示函數須要接收*個參數。好了,如今有了Mock類,接下來咱們開始寫測試用例:

1 class MockFoo : public FooInterface {
2 public:
3     MockFoo() {}
4     MOCK_METHOD0(DoThis, void());
5 private:
6     GTEST_DISALLOW_COPY_AND_ASSIGN_(MockFoo);
7 };

  EXPECT_CALL宏表示將會在後面調用foo對象中的DoThis方法,而且調用次數爲1。

  一切都準備好了,如今直接make編譯運行就能夠了,運行結果爲:

  若是咱們把最後的delete foo去掉會怎麼樣?

  結果就是gmock會報錯提示內存泄露了,但須要注意的是若是在函數func裏面裏面發生了內存泄露,gmock是檢查不出來的。

  最後若是咱們把Times中預計的DoThis方法運行次數改成2,結果會怎樣?

  結果這個case運行會失敗,預計的次數和實際調用次數不符合。

總結

  上面兩個demo也只是個簡單的示例,它們僅僅展現了gtest和gmock的基本用法,這也是咱們在實際測試時常常須要用到的東西,至於一些高級的功能,須要時能夠參考官網文檔。

相關文章
相關標籤/搜索