GTest初體驗 -- 遇到運行庫libCMT衝突問題

gtest是Google開源的C++單元測試框架,之前稍接觸過boost::unittest和cmockery,這些框架的使用基本上是大同小異。因爲項目涉及到gtest,那我就藉此機會學習一下。 ios

首先是從網站上下載最新的版本:http://code.google.com/p/googletest/downloads/list ubuntu

以前在網上瀏覽了一些gtest相關的資料,聽說是須要編譯器支持C++ TR1。還好目前我用的兩個環境ubuntu gcc 4.2.4和vs2010還不須要擔憂這個問題。 框架

下了源碼包以後,首先在vs2010下編譯。在msvc目錄下有個工程文件,打開一共有4個工程:gtest, gtest_main, gtest_prod_test和gtest_unittest。把debug和release都bulid一下,前兩個生成了靜態庫.lib,後兩個生產了可執行文件.exe。目前我只關心第一個gtest,企業的之後再慢慢研究。新建了一個做爲單元測試的工程,把gtest的include路徑、lib路徑和文件都設好。 函數

[cpp]  view plain copy
  1. #include <iostream>  
  2. #include "gtest/gtest.h"  
  3.   
  4. using namespace std;  
  5.   
  6. class MyClass  
  7. {  
  8. public:  
  9.     bool returnBoolean(){return true;}  
  10. };  
  11.   
  12. class MyClassTest:public testing::Test  
  13. {  
  14. public:  
  15.     virtual void SetUp()  
  16.     {  
  17.   
  18.     }  
  19.       
  20.     virtual void TearDown()  
  21.     {  
  22.           
  23.     }  
  24.   
  25.     MyClass m_MyClass;  
  26. };  
  27.   
  28. TEST_F(MyClassTest, returnBoolean_1)  
  29. {  
  30.     bool ret;  
  31.   
  32.     ret = m_MyClass.returnBoolean();  
  33.   
  34.     EXPECT_EQ(true, ret);  
  35. }  
  36.   
  37.   
  38. //---------------------------------------------------------  
  39. int main(int argc, char* argv[])   
  40. {   
  41.     testing::InitGoogleTest(&argc,argv);   
  42.     RUN_ALL_TESTS();    
  43.     std::cin.get();   
  44.     return 0;   
  45. }   

第一次bulid出了一大堆錯誤... 單元測試

[plain]  view plain copy
  1.   
[plain]  view plain copy
  1. ..省略n多行...  
  2. 1>LIBCMTD.lib(printf.obj) : error LNK2005: _printf already defined in MSVCRTD.lib(MSVCR100D.dll)  
  3. 1>LIBCMTD.lib(vprintf.obj) : error LNK2005: _vprintf already defined in MSVCRTD.lib(MSVCR100D.dll)  
  4. 1>LINK : warning LNK4098: defaultlib 'MSVCRTD' conflicts with use of other libs; use /NODEFAULTLIB:library  

提示是符號重複定義,庫衝突了。加上連接參數/NODEFAULTLIB:libCMTD,再bulid,仍是一大堆相似的錯誤,只libcmtd.lib變成了libcpmtd。胡亂地加上/NODEFAULTLIB:libCPMTD,這回既有重複定義,又有未定義符號錯誤。試試反過來/NODEFAULTLIB:libMSVCRTD,仍是不行。看來方向不對。 學習

認真查資料得知,libCMTD.lib等庫是vs默認選用的運行庫。千辛萬苦去對比gtest工程和個人工程的構建編譯連接參數,終於發現C++代碼生成裏面runtime library項不同:個人工程裏用的是Multi-threaded Debug DLL (/MDd),而gtest用的是Multi-threaded (/MT)。因而嘗試把個人工程參數也改過來,發現仍是有錯。通過幾輪組合嘗試,終於在/MTd和/NODEFAULTLIB:libCMTD參數下構建成功。後來,我試着把gtest的編譯參數改爲/MTd從新生成。這一回個人工程參數只要跟gtest保持一致用/MTd就構建成功了。運行看到RUN OK PASSED等字樣,感受這真是不容易啊.... 測試

到這裏庫衝突問題算是已經解決,但當中的原理還不是太清楚,之後研究... 網站

最後小結gtest最基本的接口宏: google

TEST(test_case_name, test_name) - 像定義一個函數那樣創建一個測試用例,一般用於功能比較獨立的測試 spa

TEST_F(test_fixture, test_name) -  像定義一個函數那樣創建一個測試夾具,須要一個夾具類協助,一般用於須要上下文的測試

RUN_ALL_TESTS() - 放在main函數裏的東西,表示測試開始

EXPECT/ASSERT_*(expected, actual) - 測試檢查點,EXPECT/ASSERT區別是前者失敗會繼續執行,後者將退出當前函數

相關文章
相關標籤/搜索