• <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>

            woaidongmao

            文章均收錄自他人博客,但不喜標(biāo)題前加-[轉(zhuǎn)貼],因其丑陋,見諒!~
            隨筆 - 1469, 文章 - 0, 評(píng)論 - 661, 引用 - 0
            數(shù)據(jù)加載中……

            使用Google C++ Testing Framework進(jìn)行單元測(cè)試

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

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

             

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


            1.
            簡(jiǎn)單測(cè)試TEST
            假如我寫了個(gè)函數(shù),是計(jì)算階乘的:

            1.           int Factorial( int n )

            2.           {

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

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

            5.           }

            6.           //TEST做簡(jiǎn)單測(cè)試

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

            8.           {

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

            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相關(guān)的命令行開關(guān),如果不關(guān)注也可不加

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

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

            23.            return 0;

            24.       }

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

            運(yùn)行結(jié)果:

            clip_image002

            :測(cè)試框架指出:TestFactorial.ZeroInput運(yùn)行OK,運(yùn)行OtherInput時(shí)出現(xiàn)三次結(jié)果和預(yù)期不符。

             

            2.多個(gè)測(cè)試場(chǎng)景需要相同數(shù)據(jù)配置的情況,用TEST_F

            1.           //TEST_F做同配置的系列測(cè)試

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

            3.           struct FooTest : testing::Test {

            4.            //這里定義要測(cè)試的東東

            5.           tstring strExe;

            6.            //可以利用構(gòu)造、析構(gòu)來初始化一些參數(shù)

            7.           FooTest() {}

            8.            virtual ~FooTest() {}

            9.            //如果構(gòu)造、析構(gòu)還不能滿足你,還有下面兩個(gè)虛擬函數(shù)

            10.        virtual void SetUp() {

            11.         // 在構(gòu)造后調(diào)用

            12.         strExe.resize(MAX_PATH);

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

            14.       }

            15.        virtual void TearDown() { }   // 在析構(gòu)前調(diào)用

            16.       };

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

            18.       {

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

            20.       }

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

            22.       {

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

            24.       }

            25.       TEST_F(FooTest, Test_GFN) //測(cè)試getfilename函數(shù)

            26.       {

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

            28.       }

            29.       TEST_F(FooTest, Test_GP) //測(cè)試getpath函數(shù)

            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[])  //主函數(shù)還是一樣地

            34.       {

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

            36.       RUN_ALL_TESTS();

            37.            std::cin.get();

            38.            return 0;

            39.       }

             

            運(yùn)行結(jié)果:

            clip_image004

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

             

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

            斷言列表:

            真假條件測(cè)試:

             

             

            致命斷言

            非致命斷言

            驗(yàn)證條件

            ASSERT_TRUE(condition);

            EXPECT_TRUE(condition);

            condition為真

            ASSERT_FALSE(condition);

            EXPECT_FALSE(condition);

            condition 為假

             

            數(shù)據(jù)對(duì)比測(cè)試:

             

             

            致命斷言

            非致命斷言

            驗(yàn)證條件

            ASSERT_EQ(期望值, 實(shí)際值);

            EXPECT_EQ(期望值, 實(shí)際值);

            期望值 == 實(shí)際值

            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

             

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

             

             

            致命斷言

            非致命斷言

            驗(yàn)證條件

            ASSERT_STREQ(expected_str, actual_str);

            EXPECT_STREQ(expected_str, actual_str);

            兩個(gè)C字符串有相同的內(nèi)容

            ASSERT_STRNE(str1, str2);

            EXPECT_STRNE(str1, str2);

            兩個(gè)C字符串有不同的內(nèi)容

            ASSERT_STRCASEEQ(expected_str, actual_str);

            EXPECT_STRCASEEQ(expected_str, actual_str);

            兩個(gè)C字符串有相同的內(nèi)容,忽略大小寫

            ASSERT_STRCASENE(str1, str2);

            EXPECT_STRCASENE(str1, str2);

            兩個(gè)C字符串有不同的內(nèi)容,忽略大小寫

             

             

            TEST:

            TEST宏的作用是創(chuàng)建一個(gè)簡(jiǎn)單測(cè)試,它定義了一個(gè)測(cè)試函數(shù),在這個(gè)函數(shù)里可以使用任何C++代碼并使用上面提供的斷言來進(jìn)行檢查。

            TEST第一個(gè)參數(shù)是測(cè)試用例名,第二個(gè)參數(shù)是測(cè)試用例中某項(xiàng)測(cè)試的名稱。一個(gè)測(cè)試用例可以包含任意數(shù)量的獨(dú)立測(cè)試。這兩個(gè)參數(shù)組成了一個(gè)測(cè)試的全稱。

            就前面的例子來說:

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

            我們的測(cè)試用例是:測(cè)試輸入0的情況,測(cè)試輸入其它數(shù)據(jù)的情況,于是就有了:

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

            2.           {

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

            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根據(jù)測(cè)試用例來分組收集測(cè)試結(jié)果,因此,邏輯相關(guān)的測(cè)試應(yīng)該在同一測(cè)試用例中;換句話說,它們的TEST()的第一個(gè)參數(shù)應(yīng)該是一樣的。在上面的例子中,我們有兩個(gè)測(cè)試,ZeroInputOtherInput,它們都屬于同一個(gè)測(cè)試用例TestFactorial

             

            TEST_F:

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

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

            要?jiǎng)?chuàng)建測(cè)試固件,只需:

            1.           創(chuàng)建一個(gè)類繼承自testing::Test。將其中的成員聲明為protected:或是public:,因?yàn)槲覀兿胍獜淖宇愔写嫒A具成員。

            2.           在該類中聲明測(cè)試中所要使用到的數(shù)據(jù)。

            3.           如果需要,編寫一個(gè)默認(rèn)構(gòu)造函數(shù)或者SetUp()函數(shù)來為每個(gè)測(cè)試準(zhǔn)備對(duì)象。

            4.           如果需要,編寫一個(gè)析構(gòu)函數(shù)或者TearDown()函數(shù)來釋放你在SetUp()函數(shù)中申請(qǐng)的資源。

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

            當(dāng)我們要使用固件時(shí),使用TEST_F()替換掉TEST(),它允許我們存取測(cè)試固件中的對(duì)象和子程序:

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

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

            對(duì)于TEST_F()中定義的每個(gè)測(cè)試,Google Test將會(huì):

            1.           創(chuàng)建一個(gè)全新的測(cè)試夾具

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

            3.           運(yùn)行測(cè)試

            4.           調(diào)用TearDown()來進(jìn)行清理工作

            5.           刪除測(cè)試夾具。

            注意,同一測(cè)試用例中,不同的測(cè)試擁有不同的測(cè)試夾具。Google Test不會(huì)對(duì)多個(gè)測(cè)試重用一個(gè)測(cè)試夾具,測(cè)試對(duì)測(cè)試夾具的改動(dòng)并不會(huì)影響到其他測(cè)試。

             

            調(diào)用測(cè)試

            TEST()TEST_F()Google Test隱式注冊(cè)它們的測(cè)試。因此,與很多其他的C++測(cè)試框架不同,你不需要為了運(yùn)行你定義的測(cè)試而將它們?nèi)吭倭谐鰜硪淮巍?

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

            當(dāng)被調(diào)用時(shí),RUN_ALL_TESTS()宏會(huì):

            1.           保存所有的Google Test標(biāo)志。

            2.           為一個(gè)測(cè)試創(chuàng)建測(cè)試夾具對(duì)象。

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

            4.           在固件對(duì)象上運(yùn)行測(cè)試。

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

            6.           刪除固件。

            7.           恢復(fù)所有Google Test標(biāo)志的狀態(tài)。

            8.           重復(fù)上訴步驟,直到所有測(cè)試完成。

            此外,如果第二步時(shí),測(cè)試夾具的構(gòu)造函數(shù)產(chǎn)生一個(gè)致命錯(cuò)誤,繼續(xù)執(zhí)行35部顯然沒有必要,所以它們會(huì)被跳過。與之相似,如果第3部產(chǎn)生致命錯(cuò)誤,第4部也會(huì)被跳過。

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

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

             

            編寫main()函數(shù)

            你可以從下面這個(gè)模板開始:

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

            2.           #include <gtest/gtest.h>

            3.           namespace {

            4.           // 測(cè)試Foo類的測(cè)試固件

            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() 函數(shù)負(fù)責(zé)解析命令行傳入的Google Test標(biāo)志,并刪除所有它可以處理的標(biāo)志。這使得用戶可以通過各種不同的標(biāo)志控制一個(gè)測(cè)試程序的行為。關(guān)于這一點(diǎn)我們會(huì)在GTestAdvanced中講到。你必須在調(diào)用RUN_ALL_TESTS()之前調(diào)用該函數(shù),否則就無法正確地初始化標(biāo)示。

            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

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

            lizhe1985 發(fā)表于20081231 8:58:11  IP:舉報(bào)

            您的文章已經(jīng)被推薦到CSDN首頁(yè)專家專欄欄目,將被更多的CSDN網(wǎng)友閱讀與分享。感謝您對(duì)CSDN博客的支持。

            wslgz 發(fā)表于20081231 15:37:49  IP:舉報(bào)

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

            wslgz 發(fā)表于20081231 15:37:58  IP:舉報(bào)

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

            wslgz 發(fā)表于20081231 15:38:31  IP:舉報(bào)

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

            cairuichu 發(fā)表于20081231 17:10:52  IP:舉報(bào)

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

            cairuichu 發(fā)表于20081231 17:10:56  IP:舉報(bào)

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

            cairuichu 發(fā)表于20081231 17:11:01  IP:舉報(bào)

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

            Waiting4you 發(fā)表于200911 11:51:59  IP:舉報(bào)

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

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

            博主,我是第一次用vs2005,但是在實(shí)驗(yàn)?zāi)愕奈恼轮谐霈F(xiàn)了很多問題,解決了一些,最后還是有一個(gè)棘手的,能幫我解決一下嗎?可能是編譯時(shí)的鏈接問題: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個(gè),你知道怎么解決呢?

            Waiting4you 發(fā)表于200912 10:15:08  IP:舉報(bào)

            olay105:
            先打開msvc\gtest.sln,編譯,生成Debug\gtestd.libRelease\gtest.lib,這是庫(kù)文件。
            把這個(gè)gtest.libgtestd.lib加入到這個(gè)出現(xiàn)很多問題的工程里。注意,因?yàn)閹?kù)文件工程里默認(rèn)是運(yùn)行時(shí)庫(kù):多線程,所以你的工程也要這么設(shè)置。

            olay105 發(fā)表于200913 17:34:00  IP:舉報(bào)

            謝謝博主,我已經(jīng)解決問題了,很開心!

            koolhazz 發(fā)表于200918 15:35:00  IP:舉報(bào)

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

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

            koolhazz 發(fā)表于200918 15:35:12  IP:舉報(bào)

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

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

             

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

            国产美女亚洲精品久久久综合| 久久精品国产精品青草| 人人狠狠综合久久亚洲88| 亚洲AV日韩精品久久久久久| 国产99久久久国产精品小说| 亚洲综合久久夜AV | 久久久久久国产精品无码下载| 国产 亚洲 欧美 另类 久久| 99久久精品免费| 久久精品不卡| 怡红院日本一道日本久久| 国产福利电影一区二区三区久久久久成人精品综合 | 亚洲精品无码久久久| 久久综合视频网站| 亚洲国产精品成人久久蜜臀 | 日韩电影久久久被窝网| 久久久久久国产精品美女| 热久久最新网站获取| 色88久久久久高潮综合影院 | 久久人妻少妇嫩草AV无码专区| 99久久99这里只有免费的精品| 99久久精品费精品国产| 亚洲性久久久影院| 久久精品国产亚洲AV大全| 青青草原1769久久免费播放| 久久久久九国产精品| 欧美午夜精品久久久久免费视 | 久久久免费观成人影院| 囯产极品美女高潮无套久久久| 久久国产乱子伦免费精品| 国产99久久久久久免费看| 久久综合九色综合网站| 久久中文娱乐网| 亚洲伊人久久成综合人影院 | 一级做a爰片久久毛片看看| 日产精品99久久久久久| 国产真实乱对白精彩久久| 日韩人妻无码一区二区三区久久 | 久久国产精品无码一区二区三区 | 国产91色综合久久免费| 欧美一区二区久久精品|