青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

woaidongmao

文章均收錄自他人博客,但不喜標題前加-[轉貼],因其丑陋,見諒!~
隨筆 - 1469, 文章 - 0, 評論 - 661, 引用 - 0
數據加載中……

使用Google C++ Testing Framework進行單元測試

前幾個月Google開源了它的測試框架,自稱其旗下的上千個項目都在使用它。今天我們就用它來嘗嘗鮮吧?:-)

安裝:
下載Google C++ Testing Framework,解壓...
VC2005:
   
直接打開msvc\gtest.vcprojmsvc\gtest.sln,直接編譯即可。
Linux/Unix
下的GCC:
   
傳統過程:./configure  make
Mingw:
BCC:
   
MingwBCB6編譯需要修改一些代碼,過幾天我會上傳到www.cppprog.com網站上。

 

使用:
首先#include <gtest/gtest.h>,當然工程的頭文件路徑要設置正確


1.
簡單測試TEST
假如我寫了個函數,是計算階乘的:

1.           int Factorial( int n )

2.           {

3.            if(n==2) return 100; //故意出個錯,嘻嘻

4.            return n<=0? 1 : n*Factorial(n - 1);

5.           }

6.           //TEST做簡單測試

7.           TEST(TestFactorial, ZeroInput) //第一個參數是測試用例名,第二個參數是測試名:隨后的測試結果將以"測試用例名.測試名"的形式給出

8.           {

9.           EXPECT_EQ(1, Factorial(0));  //EXPECT_EQ稍候再說,現在只要知道它是測試兩個數據是否相等的就行了。

10.       }

11.       TEST(TestFactorial, OtherInput)

12.       {

13.       EXPECT_EQ(1, Factorial(1));

14.       EXPECT_EQ(2, Factorial(2));

15.       EXPECT_EQ(6, Factorial(3));

16.       EXPECT_EQ(40320, Factorial(8));

17.      

18.       int main(int argc, TCHAR* argv[])

19.       {

20.       testing::InitGoogleTest(&argc,argv); //用來處理Test相關的命令行開關,如果不關注也可不加

21.       RUN_ALL_TESTS();  //看函數名就知道干啥了

22.            std::cin.get();   //只是讓它暫停而已,不然一閃就沒了

23.            return 0;

24.       }

25.       //---------------------------------------------------------------------------

運行結果:

clip_image002

:測試框架指出:TestFactorial.ZeroInput運行OK,運行OtherInput時出現三次結果和預期不符。

 

2.多個測試場景需要相同數據配置的情況,用TEST_F

1.           //TEST_F做同配置的系列測試

2.           typedef std::basic_string<TCHAR> tstring;

3.           struct FooTest : testing::Test {

4.            //這里定義要測試的東東

5.           tstring strExe;

6.            //可以利用構造、析構來初始化一些參數

7.           FooTest() {}

8.            virtual ~FooTest() {}

9.            //如果構造、析構還不能滿足你,還有下面兩個虛擬函數

10.        virtual void SetUp() {

11.         // 在構造后調用

12.         strExe.resize(MAX_PATH);

13.         GetModuleFileName(NULL, &strExe[0], MAX_PATH);

14.       }

15.        virtual void TearDown() { }   // 在析構前調用

16.       };

17.       tstring getfilename(const tstring &full)  //偶寫的從完整路徑里取出文件名的函數(路徑分隔符假定為'\\')

18.       {

19.        return full.substr(full.rfind(_T('\\')));

20.       }

21.       tstring getpath(const tstring &full)   //偶寫的從完整路徑里取出路徑名的函數(Windows路徑)

22.       {

23.        return full.substr(0, full.rfind(_T('\\')));

24.       }

25.       TEST_F(FooTest, Test_GFN) //測試getfilename函數

26.       {

27.       EXPECT_STREQ(_T("Project1.exe"), getfilename(strExe).c_str());

28.       }

29.       TEST_F(FooTest, Test_GP) //測試getpath函數

30.       {

31.       EXPECT_STREQ(_T("D:\\Code\\libs\\google\\gtest-1.2.1\\BCC_SPC\\bcc\\ex"), getpath(strExe).c_str());

32.       }

33.       int main(int argc, TCHAR* argv[])  //主函數還是一樣地

34.       {

35.       testing::InitGoogleTest(&argc,argv);

36.       RUN_ALL_TESTS();

37.            std::cin.get();

38.            return 0;

39.       }

 

運行結果:

clip_image004

瞧,Google C++ 測試框架毫不客氣地指出偶的getfilename返回的字符串比預期的多了一個'\\'

 

快速入門:
Google
提供了兩種斷言形式,一種以ASSERT_開頭,另一種以EXPECT_開頭,它們的區別是ASSERT_*一旦失敗立馬退出,而EXPECT_還能繼續下去。

斷言列表:

真假條件測試:

 

 

致命斷言

非致命斷言

驗證條件

ASSERT_TRUE(condition);

EXPECT_TRUE(condition);

condition為真

ASSERT_FALSE(condition);

EXPECT_FALSE(condition);

condition 為假

 

數據對比測試:

 

 

致命斷言

非致命斷言

驗證條件

ASSERT_EQ(期望值, 實際值);

EXPECT_EQ(期望值, 實際值);

期望值 == 實際值

ASSERT_NE(val1, val2);

EXPECT_NE(val1, val2);

val1 != val2

ASSERT_LT(val1, val2);

EXPECT_LT(val1, val2);

val1 < val2

ASSERT_LE(val1, val2);

EXPECT_LE(val1, val2);

val1 <= val2

ASSERT_GT(val1, val2);

EXPECT_GT(val1, val2);

val1 > val2

ASSERT_GE(val1, val2);

EXPECT_GE(val1, val2);

val1 >= val2

 

字符串(針對C形式的字符串,即char*wchar_t*)對比測試:

 

 

致命斷言

非致命斷言

驗證條件

ASSERT_STREQ(expected_str, actual_str);

EXPECT_STREQ(expected_str, actual_str);

兩個C字符串有相同的內容

ASSERT_STRNE(str1, str2);

EXPECT_STRNE(str1, str2);

兩個C字符串有不同的內容

ASSERT_STRCASEEQ(expected_str, actual_str);

EXPECT_STRCASEEQ(expected_str, actual_str);

兩個C字符串有相同的內容,忽略大小寫

ASSERT_STRCASENE(str1, str2);

EXPECT_STRCASENE(str1, str2);

兩個C字符串有不同的內容,忽略大小寫

 

 

TEST:

TEST宏的作用是創建一個簡單測試,它定義了一個測試函數,在這個函數里可以使用任何C++代碼并使用上面提供的斷言來進行檢查。

TEST第一個參數是測試用例名,第二個參數是測試用例中某項測試的名稱。一個測試用例可以包含任意數量的獨立測試。這兩個參數組成了一個測試的全稱。

就前面的例子來說:

我們要測試這個函數:int Factorial(int n); // 返回n的階乘

我們的測試用例是:測試輸入0的情況,測試輸入其它數據的情況,于是就有了:

1.           TEST(TestFactorial, ZeroInput) //第一個參數是測試用例名,第二個參數是測試名:隨后的測試結果將以"測試用例名.測試名"的形式給出

2.           {

3.           EXPECT_EQ(1, Factorial(0));  //EXPECT_EQ稍候再說,現在只要知道它是測試兩個數據是否相等的就行了。

4.           }

5.           TEST(TestFactorial, OtherInput)

6.           {

7.           EXPECT_EQ(1, Factorial(1));

8.           EXPECT_EQ(2, Factorial(2));

9.           EXPECT_EQ(6, Factorial(3));

10.       EXPECT_EQ(40320, Factorial(8));

11.       }

 

Google Test根據測試用例來分組收集測試結果,因此,邏輯相關的測試應該在同一測試用例中;換句話說,它們的TEST()的第一個參數應該是一樣的。在上面的例子中,我們有兩個測試,ZeroInputOtherInput,它們都屬于同一個測試用例TestFactorial

 

TEST_F:

TEST_F宏用于在多個測試中使用同樣的數據配置,所以它又叫:測試夾具(Test Fixtures

如果我們的多個測試要使用相同的數據(如前例中,我們的Test_GFNTest_GP都使用程序自身的完整文件名來測試),就可以采用一個測試夾具。

要創建測試固件,只需:

1.           創建一個類繼承自testing::Test。將其中的成員聲明為protected:或是public:,因為我們想要從子類中存取夾具成員。

2.           在該類中聲明測試中所要使用到的數據。

3.           如果需要,編寫一個默認構造函數或者SetUp()函數來為每個測試準備對象。

4.           如果需要,編寫一個析構函數或者TearDown()函數來釋放你在SetUp()函數中申請的資源。

5.           如果需要,定義你的測試所需要共享的子程序。

當我們要使用固件時,使用TEST_F()替換掉TEST(),它允許我們存取測試固件中的對象和子程序:

TEST_F(test_case_name, test_name) {
... test body ...
}

TEST()一樣,第一個參數是測試用例的名稱,但對TEST_F()來說,這個名稱必須與測試夾具類的名稱一樣。

對于TEST_F()中定義的每個測試,Google Test將會:

1.           創建一個全新的測試夾具

2.           通過SetUp()初始化它,

3.           運行測試

4.           調用TearDown()來進行清理工作

5.           刪除測試夾具。

注意,同一測試用例中,不同的測試擁有不同的測試夾具。Google Test不會對多個測試重用一個測試夾具,測試對測試夾具的改動并不會影響到其他測試。

 

調用測試

TEST()TEST_F()Google Test隱式注冊它們的測試。因此,與很多其他的C++測試框架不同,你不需要為了運行你定義的測試而將它們全部再列出來一次。

在定義好測試后,你可以通過RUN_ALL_TESTS()來運行它們,如果所有測試成功,該函數返回0,否則會返回1.注意RUN_ALL_TESTS()會運行你鏈接到的所有測試——它們可以來自不同的測試用例,甚至是來自不同的文件。

當被調用時,RUN_ALL_TESTS()宏會:

1.           保存所有的Google Test標志。

2.           為一個測試創建測試夾具對象。

3.           調用SetUp()初始化它。

4.           在固件對象上運行測試。

5.           調用TearDown()清理夾具。

6.           刪除固件。

7.           恢復所有Google Test標志的狀態。

8.           重復上訴步驟,直到所有測試完成。

此外,如果第二步時,測試夾具的構造函數產生一個致命錯誤,繼續執行35部顯然沒有必要,所以它們會被跳過。與之相似,如果第3部產生致命錯誤,第4部也會被跳過。

重要:你不能忽略掉RUN_ALL_TESTS()的返回值,否則gcc會報一個編譯錯誤。這樣設計的理由是自動化測試服務會根據測試退出返回碼來決定一個測試是否通過,而不是根據其stdout/stderr輸出;因此你的main()函數必須返回RUN_ALL_TESTS()的值。

而且,你應該只調用RUN_ALL_TESTS()一次。多次調用該函數會與Google Test的一些高階特性(如線程安全死亡測試thread-safe death tests)沖突,因而是不被支持的。

 

編寫main()函數

你可以從下面這個模板開始:

1.           #include "this/package/foo.h"

2.           #include <gtest/gtest.h>

3.           namespace {

4.           // 測試Foo類的測試固件

5.           class FooTest : public testing::Test {

6.           protected:

7.             // You can remove any or all of the following functions if its body

8.             // is empty.

9.             FooTest() {

10.           // You can do set-up work for each test here.

11.         }

12.         virtual ~FooTest() {

13.           // You can do clean-up work that doesn't throw exceptions here.

14.         }

15.         // If the constructor and destructor are not enough for setting up

16.         // and cleaning up each test, you can define the following methods:

17.         virtual void SetUp() {

18.           // Code here will be called immediately after the constructor (right

19.           // before each test).

20.         }

21.         virtual void TearDown() {

22.           // Code here will be called immediately after each test (right

23.           // before the destructor).

24.         }

25.         // Objects declared here can be used by all tests in the test case for Foo.

26.       };

27.       // Tests that the Foo::Bar() method does Abc.

28.       TEST_F(FooTest, MethodBarDoesAbc) {

29.         const string input_filepath = "this/package/testdata/myinputfile.dat";

30.         const string output_filepath = "this/package/testdata/myoutputfile.dat";

31.         Foo f;

32.         EXPECT_EQ(0, f.Bar(input_filepath, output_filepath));

33.       }

34.       // Tests that Foo does Xyz.

35.       TEST_F(FooTest, DoesXyz) {

36.         // Exercises the Xyz feature of Foo.

37.       }

38.       // namespace

39.       int main(int argc, char **argv) {

40.         testing::InitGoogleTest(&argc, argv);

41.         return RUN_ALL_TESTS();

42.       }

 

testing::InitGoogleTest() 函數負責解析命令行傳入的Google Test標志,并刪除所有它可以處理的標志。這使得用戶可以通過各種不同的標志控制一個測試程序的行為。關于這一點我們會在GTestAdvanced中講到。你必須在調用RUN_ALL_TESTS()之前調用該函數,否則就無法正確地初始化標示。

WindowsInitGoogleTest()可以支持寬字符串,所以它也可以被用在以UNICODE模式編譯的程序中。

 

Google test for mingw 下載: http://www.cppprog.com/2009/0101/26.html Google test for bcb 下載: http://www.cppprog.com/2009/0101/27.html

發表于 @ 2008年12月30日 19:46:00|評論(13 )|收藏

lizhe1985 發表于20081231 8:58:11  IP:舉報

您的文章已經被推薦到CSDN首頁專家專欄欄目,將被更多的CSDN網友閱讀與分享。感謝您對CSDN博客的支持。

wslgz 發表于20081231 15:37:49  IP:舉報

不知道能不能給個vc的例子,有些地方不是很明白

wslgz 發表于20081231 15:37:58  IP:舉報

不知道能不能給個vc的例子,有些地方不是很明白

wslgz 發表于20081231 15:38:31  IP:舉報

不知道能不能給個vc的例子,有些地方不是很明白

cairuichu 發表于20081231 17:10:52  IP:舉報

同求vc的例子,最好6.0^_^

cairuichu 發表于20081231 17:10:56  IP:舉報

同求vc的例子,最好6.0^_^

cairuichu 發表于20081231 17:11:01  IP:舉報

同求vc的例子,最好6.0^_^

Waiting4you 發表于200911 11:51:59  IP:舉報

VC是最簡單的,從官網上下載以后里面就自帶了VC的工程文件(包含例子和庫文件),直接打開編譯就可以了。
注意庫文件默認是多線程而不是多線程DLL”
我上面的代碼就是在VC2005里修改的。
至于VC6.0,我沒試過,不過可以考慮去下載我修改的for BCB6.0的代碼,VC6.0應該也能編譯通過。

olay105 發表于200911 18:29:28  IP:
總共15個,你知道怎么解決呢? 文章鏈接:http://blog.csdn.net/Waiting4you/archive/2008/12/30/3652350.aspx 發表時間:2009年1月1 18:29:28">舉報

博主,我是第一次用vs2005,但是在實驗你的文章中出現了很多問題,解決了一些,最后還是有一個棘手的,能幫我解決一下嗎?可能是編譯時的鏈接問題:error LNK2019: unresolved external symbol "protected: __thiscall testing::Test::Test(void)" (??0Test@testing@@IAE@XZ) referenced in function "public: __thiscall TestFactorial_ZeroInput_Test::TestFactorial_ZeroInput_Test(void)" (??0TestFactorial_ZeroInput_Test@@QAE@XZ) project1.obj
總共15個,你知道怎么解決呢?

Waiting4you 發表于200912 10:15:08  IP:舉報

olay105:
先打開msvc\gtest.sln,編譯,生成Debug\gtestd.libRelease\gtest.lib,這是庫文件。
把這個gtest.libgtestd.lib加入到這個出現很多問題的工程里。注意,因為庫文件工程里默認是運行時庫:多線程,所以你的工程也要這么設置。

olay105 發表于200913 17:34:00  IP:舉報

謝謝博主,我已經解決問題了,很開心!

koolhazz 發表于200918 15:35:00  IP:舉報

樓主:
我直接使用VC2005編譯的話也是有很多錯誤,
錯誤 13 未能刪除文件“c:\code\googletest\msvc\Release\vc80.idb”
請確保該文件未被其他進程打開并且未被寫保護。 gtest_output_test_

不知道是什么原因呢?我的環境里面還安裝了vc2003
謝謝。

koolhazz 發表于200918 15:35:12  IP:舉報

樓主:
我直接使用VC2005編譯的話也是有很多錯誤,
錯誤 13 未能刪除文件“c:\code\googletest\msvc\Release\vc80.idb”
請確保該文件未被其他進程打開并且未被寫保護。 gtest_output_test_

不知道是什么原因呢?我的環境里面還安裝了vc2003
謝謝。

 

posted on 2009-05-02 01:44 肥仔 閱讀(3149) 評論(0)  編輯 收藏 引用 所屬分類: 庫 & 代碼段

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            欧美激情视频一区二区三区在线播放 | 欧美激情黄色片| 一二三区精品福利视频| 欧美国产成人精品| 99这里只有久久精品视频| 韩国视频理论视频久久| 国产伦精品一区| 欧美日韩综合不卡| 久久精品道一区二区三区| 午夜精品福利电影| 亚洲欧美中文在线视频| 亚洲欧美日韩国产另类专区| 亚洲男女自偷自拍图片另类| 亚洲午夜久久久久久尤物| 在线亚洲自拍| 亚洲在线免费视频| 亚洲欧美视频一区| 欧美一区二区三区四区高清| 亚洲欧美视频在线观看视频| 午夜精品久久久久久久99樱桃 | 亚洲综合首页| 亚洲午夜久久久久久久久电影院 | 亚洲乱码国产乱码精品精98午夜| 激情综合在线| 影音先锋成人资源站| 在线观看欧美黄色| 亚洲精品国产精品国自产观看浪潮| 亚洲国产精品日韩| 亚洲视频网在线直播| 亚洲综合精品一区二区| 久久精品在线免费观看| 麻豆精品国产91久久久久久| 亚洲国产精品www| 亚洲精品国产精品乱码不99 | 国内免费精品永久在线视频| 国模大胆一区二区三区| 1769国产精品| 一区二区三区视频在线| 一区二区三区 在线观看视频| 亚洲综合首页| 久久久久青草大香线综合精品| 亚洲欧美成人| 猛男gaygay欧美视频| 亚洲欧洲精品一区| 亚洲国产专区| 亚洲欧美日韩一区在线| 欧美jizzhd精品欧美巨大免费| 欧美午夜www高清视频| 伊人久久亚洲热| 极品少妇一区二区三区| 在线综合欧美| 久久综合给合| 亚洲视屏在线播放| 免费一级欧美片在线播放| 欧美高清视频一区| 国产亚洲欧美一区在线观看| 日韩一区二区免费高清| 久久久99精品免费观看不卡| 亚洲精品视频在线观看网站| 亚洲国产另类久久精品| 欧美新色视频| 国产欧美亚洲日本| aa成人免费视频| 久久夜色精品一区| 亚洲国产日韩在线一区模特| 欧美一区二区三区另类| 欧美婷婷久久| 国产人成一区二区三区影院| 一区二区三区www| 欧美91大片| 欧美在线影院| 99精品福利视频| 夜夜嗨av色一区二区不卡| 免费观看成人| 在线不卡欧美| 另类图片国产| 久久精品国产亚洲aⅴ| 国产精品资源在线观看| 亚洲影院在线观看| 99视频精品全部免费在线| 免费影视亚洲| 亚洲人在线视频| 亚洲电影第三页| 久久午夜激情| 亚洲人成亚洲人成在线观看| 久久综合五月| 久久久久久9999| 国产一区二区三区四区| 久久精品女人| 久久精彩视频| 亚洲盗摄视频| 亚洲电影成人| 欧美日韩一区二区三区高清| 亚洲免费在线视频| 久久精品一二三区| 一区二区三区久久久| 欧美亚洲三区| 99re66热这里只有精品4| 午夜久久久久久久久久一区二区| 亚洲欧美日韩中文在线制服| 激情六月婷婷久久| 亚洲免费成人av| 一区在线影院| 一区二区三区导航| 91久久精品久久国产性色也91| 亚洲少妇自拍| 亚洲美女在线视频| 欧美影院精品一区| 一区二区不卡在线视频 午夜欧美不卡在| 亚洲一区二区三区免费在线观看| 在线电影国产精品| 亚洲男人第一网站| 夜夜爽av福利精品导航 | 亚洲精一区二区三区| 欧美一区午夜精品| 亚洲视频日本| 欧美激情小视频| 麻豆九一精品爱看视频在线观看免费| 欧美日韩视频在线观看一区二区三区| 久久久久国产精品麻豆ai换脸| 欧美日韩亚洲一区二区三区| 欧美成人国产一区二区| 国产欧美三级| 亚洲视屏一区| 亚洲一区日韩| 欧美国产一区视频在线观看| 欧美 日韩 国产 一区| 国产亚洲精品7777| 亚洲欧美日韩爽爽影院| 午夜精品久久久久久久蜜桃app | 99视频精品| 亚洲人成小说网站色在线| 久久久蜜桃精品| 久久午夜国产精品| 黄色国产精品| 久久久精品日韩| 久久只精品国产| 狠狠色综合网| 久久久中精品2020中文| 久久福利影视| 国产午夜精品全部视频在线播放| 这里只有精品电影| 欧美99在线视频观看| 欧美**人妖| 亚洲激情一区二区三区| 欧美成人激情视频| 亚洲精品久久久久久一区二区| 日韩天堂在线观看| 欧美精品一区二区三区久久久竹菊| 亚洲国产成人tv| 在线中文字幕日韩| 国产精品永久免费视频| 欧美一区二区精品久久911| 久久先锋资源| 亚洲免费久久| 国产精品九九久久久久久久| 亚洲欧美在线另类| 欧美粗暴jizz性欧美20| 一区二区三区高清不卡| 国产精品久久久久久久免费软件| 亚洲欧美国产一区二区三区| 久久综合网络一区二区| 亚洲免费观看在线视频| 国产精品国产三级欧美二区| 香蕉成人久久| 亚洲高清视频一区二区| 亚洲欧美国产高清va在线播| 国内精品模特av私拍在线观看| 欧美sm重口味系列视频在线观看| 亚洲精品在线免费| 先锋影音国产精品| 亚洲国产成人高清精品| 欧美日韩日本网| 久久久成人网| 日韩亚洲国产欧美| 麻豆精品传媒视频| 亚洲欧美www| 亚洲国产精品一区二区尤物区| 欧美日韩成人免费| 欧美一区二区三区免费视| 亚洲精品老司机| 久久久久国产精品午夜一区| 亚洲精品网站在线播放gif| 国产欧美在线视频| 欧美日韩国产在线一区| 久久国产黑丝| aⅴ色国产欧美| 欧美mv日韩mv国产网站| 亚洲欧美日本伦理| 日韩视频亚洲视频| 一区在线播放视频| 国产丝袜美腿一区二区三区| 欧美日韩国产精品| 久久伊人精品天天| 亚洲欧美激情视频在线观看一区二区三区| 欧美大片在线看| 久久天天狠狠| 欧美一区成人| 亚洲一区二区三区精品在线 | 亚洲黄色av|