中文字幕日韩精品一区二区免费_精品一区二区三区国产精品无卡在_国精品无码专区一区二区三区_国产αv三级中文在线

C/C++中g(shù)test怎么用

這篇文章主要介紹了C/C++中g(shù)test怎么用,具有一定借鑒價(jià)值,感興趣的朋友可以參考下,希望大家閱讀完這篇文章之后大有收獲,下面讓小編帶著大家一起了解一下。

創(chuàng)新互聯(lián)主要從事成都網(wǎng)站建設(shè)、網(wǎng)站建設(shè)、網(wǎng)頁設(shè)計(jì)、企業(yè)做網(wǎng)站、公司建網(wǎng)站等業(yè)務(wù)。立足成都服務(wù)東烏珠穆沁,十年網(wǎng)站建設(shè)經(jīng)驗(yàn),價(jià)格優(yōu)惠、服務(wù)專業(yè),歡迎來電咨詢建站服務(wù):18980820575

Google C++ Testing Framework(簡稱gtest,http://code.google.com/p/googletest/)是Google公司發(fā)布的一個(gè)開源C/C++單元測試框架,已被應(yīng)用于多個(gè)開源項(xiàng)目及Google內(nèi)部項(xiàng)目中,知名的例子包括Chrome Web瀏覽器、LLVM編譯器架構(gòu)、Protocol Buffers數(shù)據(jù)交換格式及工具等。

優(yōu)秀的C/C++單元測試框架并不算少,相比之下gtest仍具有明顯優(yōu)勢。與CppUnit比,gtest需要使用的頭文件和函數(shù)宏更集中,并支持測試用例的自動(dòng)注冊(cè)。與CxxUnit比,gtest不要求Python等外部工具的存在。與Boost.Test比,gtest更簡潔容易上手,實(shí)用性也并不遜色。Wikipedia給出了各種編程語言的單元測試框架列表(http://en.wikipedia.org/wiki/List_of_unit_testing_frameworks)。

一、基本用法

gtest當(dāng)前的版本是1.5.0,如果使用Visual C++編譯,要求編譯器版本不低于7.1(Visual C++ 2003)。如下圖所示,它的msvc文件夾包含Visual C++工程和項(xiàng)目文件,samples文件夾包含10個(gè)使用范例。

C/C++中g(shù)test怎么用

一般情況下,我們的單元測試代碼只需要包含頭文件gtest.h。gtest中常用的所有結(jié)構(gòu)體、類、函數(shù)、常量等,都通過命名空間testing訪問,不過gtest已經(jīng)把最簡單常用的單元測試功能包裝成了一些帶參數(shù)宏,因此在簡單的測試中常常可以忽略命名空間的存在。

按照gtest的叫法,宏TEST為特定的測試用例(Test Case)定義了一個(gè)可執(zhí)行的測試(Test)。它接受用戶指定的測試用例名(一般取被測對(duì)象名)和測試名作為參數(shù),并劃出了一個(gè)作用域供填充測試宏語句和普通的C++代碼。一系列TEST的集合就構(gòu)成一個(gè)簡單的測試程序。

常用的測試宏如下表所示。以ASSERT_開頭和以EXPECT_開頭的宏的區(qū)別是,前者在測試失敗時(shí)會(huì)給出報(bào)告并立即終止測試程序,后者在報(bào)告后繼續(xù)執(zhí)行測試程序。

ASSERT宏

EXPECT宏

功能

ASSERT_TRUE

EXPECT_TRUE

判真

ASSERT_FALSE

EXPECT_FALSE

判假

ASSERT_EQ

EXPECT_EQ

相等

ASSERT_NE

EXPECT_NE

不等

ASSERT_GT

EXPECT_GT

大于

ASSERT_LT

EXPECT_LT

小于

ASSERT_GE

EXPECT_GE

大于或等于

ASSERT_LE

EXPECT_LE

小于或等于

ASSERT_FLOAT_EQ

EXPECT_FLOAT_EQ

單精度浮點(diǎn)值相等

ASSERT_DOUBLE_EQ

EXPECT_DOUBLE_EQ

雙精度浮點(diǎn)值相等

ASSERT_NEAR

EXPECT_NEAR

浮點(diǎn)值接近(第3個(gè)參數(shù)為誤差閾值)

ASSERT_STREQ

EXPECT_STREQ

C字符串相等

ASSERT_STRNE

EXPECT_STRNE

C字符串不等

ASSERT_STRCASEEQ

EXPECT_STRCASEEQ

C字符串相等(忽略大小寫)

ASSERT_STRCASENE

EXPECT_STRCASENE

C字符串不等(忽略大小寫)

ASSERT_PRED1

EXPECT_PRED1

自定義謂詞函數(shù),(pred, arg1)(還有_PRED2, ..., _PRED5

寫個(gè)簡單的測試試一下。假設(shè)我們實(shí)現(xiàn)了一個(gè)加法函數(shù):

// add.h  #pragma once  inline int Add(int i, int j) { return i+j; }

對(duì)應(yīng)的單元測試程序可以這樣寫:

// add_unittest.cpp  #include "add.h"  #include <gtest/gtest.h>     TEST(Add, 負(fù)數(shù)) {   EXPECT_EQ(Add(-1,-2), -3);   EXPECT_GT(Add(-4,-5), -6); // 故意的  }     TEST(Add, 正數(shù)) {   EXPECT_EQ(Add(1,2), 3);   EXPECT_GT(Add(4,5), 6);  }

代碼中,測試用例Add包含兩個(gè)測試,正數(shù)和負(fù)數(shù)(這里利用了Visual C++ 2005以上允許標(biāo)識(shí)符包含Unicode字符的特性)。編譯運(yùn)行效果如下:

在控制臺(tái)界面中,通過的測試用綠色表示,失敗的測試用紅色表示。雙橫線分隔了不同的測試用例,其中包含的每個(gè)測試的啟動(dòng)與結(jié)果用單橫線和RUN ... OK或RUN ... FAILED標(biāo)出。失敗的測試會(huì)打印出代碼行和原因,測試程序***為所有用例和測試顯示統(tǒng)計(jì)結(jié)果。建議讀者試一下?lián)Q成ASSERT_宏的不同之處。

每個(gè)測試宏還可以使用<<運(yùn)算符在測試失敗時(shí)輸出自定義信息,如:

ASSERT_EQ(M[i], N[j]) << "i = " << i << ", j = " << j;

編譯命令行中,gtest_mt.lib和gtest_main_mt.lib就是前面使用VC項(xiàng)目文件生成的靜態(tài)庫。有意思的是,測試代碼不需要注冊(cè)測試用例,也不需要定義main函數(shù),這是gtest通過后一個(gè)靜態(tài)庫自動(dòng)完成的,它的實(shí)現(xiàn)代碼如下:

// gtest-main.cc  int main(int argc, char **argv) {   std::cout << "Running main() from gtest_main.cc\n";   testing::InitGoogleTest(&argc, argv);   return RUN_ALL_TESTS();  }

其中,函數(shù)InitGoogleTest負(fù)責(zé)注冊(cè)需要運(yùn)行的所有測試用例,宏RUN_ALL_TEST負(fù)責(zé)執(zhí)行所有測試,如果全部成功則返回0,否則返回1。當(dāng)然,我們也可以僅鏈接gtest_mt.lib,自己提供main函數(shù)。

二、測試固件

很多時(shí)候,我們想在不同的測試執(zhí)行前創(chuàng)建相同的配置環(huán)境,在測試執(zhí)行結(jié)束后執(zhí)行相應(yīng)的清理工作,測試固件(Test Fixture)為這種需求提供了方便?!癋ixture”是一個(gè)漢語中不易直接對(duì)應(yīng)的詞,《美國傳統(tǒng)詞典》對(duì)它的解釋是“(作為附屬物的)固定裝置;被固定的狀態(tài)”。在單元測試中,F(xiàn)ixture的作用是為測試創(chuàng)建輔助性的上下文環(huán)境,實(shí)現(xiàn)測試的初始化和終結(jié)與測試過程本身的分離,便于不同測試使用相同代碼來搭建固定的配置環(huán)境。用體操比賽的說法,測試過程體現(xiàn)了特定測試的自選動(dòng)作,測試固件則體現(xiàn)了對(duì)一系列測試(在開始和結(jié)束時(shí))的規(guī)定動(dòng)作。有些講單元測試的書籍直接把測試固件稱為Scaffolding(腳手架)。

使用測試固件比單純調(diào)用TEST宏稍微麻煩一些:

1.         從gtest的testing::Test類派生一個(gè)類,用public或protected定義以下所有成員。

2.         (可選)建立環(huán)境:使用默認(rèn)構(gòu)造函數(shù),或定義一個(gè)虛成員函數(shù)virtual void SetUp()。

3.         (可選)銷毀環(huán)境:使用析構(gòu)函數(shù),或定義一個(gè)虛成員函數(shù)virtual void TearDown()。

4.         用TEST_F定義測試,寫法與TEST相同,但測試用例名必須為上面定義的類名。

每個(gè)帶固件的測試的執(zhí)行順序是:

1.         調(diào)用默認(rèn)構(gòu)造函數(shù)創(chuàng)建一個(gè)新的帶固件對(duì)象。

2.         立即調(diào)用SetUp函數(shù)。

3.         運(yùn)行TEST_F體。

4.         立即調(diào)用TearDown函數(shù)。

5.         調(diào)用析構(gòu)函數(shù)銷毀類對(duì)象。

C/C++中g(shù)test怎么用

從gtest的實(shí)現(xiàn)代碼可以看到,TEST_F又從用戶定義的類自動(dòng)派生了一個(gè)類,因此要求public或protected的訪問權(quán)限;大括號(hào)里的內(nèi)容被擴(kuò)展成一個(gè)名為TestBody的虛成員函數(shù)的函數(shù)體,因此可以在其中直接訪問成員變量和成員函數(shù)。其實(shí)TEST也采用了相同的實(shí)現(xiàn)機(jī)制,只是它直接從gtest的testing::Test自動(dòng)派生類,所以可以指定任意用例名。testing::Test類的SetUp和TearDown都是空函數(shù),所以它只執(zhí)行測試步驟,沒有環(huán)境的創(chuàng)建和銷毀。

借用上面Add函數(shù)寫個(gè)固件測試的例子:

// add_unittest2.cpp  #include "add.h"  #include <stdio.h>  #include <gtest/gtest.h>     class AddTest: public testing::Test  {  public:   virtual void SetUp()    { puts("SetUp()"); }   virtual void TearDown() { puts("TearDown()"); }  };     TEST_F(AddTest, 正數(shù)) {   ASSERT_GT(Add(1,2), 3); // 故意的   ASSERT_EQ(Add(4,5), 6); // 也是故意的  }

編譯運(yùn)行效果如下:

必須強(qiáng)調(diào),每個(gè)TEST_F開始都創(chuàng)建了一個(gè)新的帶固件對(duì)象,因此每個(gè)測試都使用獨(dú)立的完全相同的初始環(huán)境,各測試可以按任意順序執(zhí)行(參見--gtest_shuffle命令行選項(xiàng))。但在某些情況下,我們可能需要在各個(gè)測試間共享一個(gè)相同的環(huán)境來保存和傳遞狀態(tài),或者環(huán)境的狀態(tài)是只讀的,可以只初始化一次,再或者創(chuàng)建環(huán)境的過程開銷很高,要求只初始化一次。共享某個(gè)固件環(huán)境的所有測試合稱為一個(gè)“測試套件”(Test Suite),gtest中利用靜態(tài)成員變量和靜態(tài)成員函數(shù)實(shí)現(xiàn)這個(gè)概念:

1.         (可選)在testing::Test的派生類中,定義若干靜態(tài)成員變量來維護(hù)套件的狀態(tài)。

2.         (可選)建立共享環(huán)境:定義一個(gè)靜態(tài)成員函數(shù)static void SetUpTestCase()。

3.         (可選)銷毀共享環(huán)境:定義一個(gè)靜態(tài)成員函數(shù)static void TearDownCase()。

另外,還可以使用gtest的Environment類來建立和銷毀所有測試共用的全局環(huán)境(對(duì)應(yīng)于上圖顯示的“Global test environment set-up”和“Global test environment tear-down”):

class Environment {   public:   virtual ~Environment() {}   virtual void SetUp() {}   virtual void TearDown() {}  };

gtest文檔建議測試程序自己定義main函數(shù)并在其中創(chuàng)建和注冊(cè)全局環(huán)境對(duì)象:

Environment* AddGlobalTestEnvironment(Environment* env);

三、異常測試

C程序中要返回出錯(cuò)信息,可以利用特定的函數(shù)返回值、函數(shù)的輸出(outbound)參數(shù)、或者設(shè)置全局變量(如C標(biāo)準(zhǔn)庫定義的errno,Windows API中的“上次錯(cuò)誤”(last error)代碼,Winsock中與每個(gè)socket相關(guān)聯(lián)的錯(cuò)誤代碼)。C++程序常用異常(exception)來返回出錯(cuò)信息,gtest為異常測試提供了專用的測試宏:

ASSERT宏

EXPECT宏

功能

ASSERT_NO_THROW

EXPECT_NO_THROW

不拋出異常,參數(shù)為(statement)

ASSERT_ANY_THROW

EXPECT_ANY_THROW

拋出異常,參數(shù)為(statement)

ASSERT_THROW

EXPECT_THROW

拋出特定類型的異常,參數(shù)為(statement, type)

需要注意,這些測試宏都接受C/C++語句作為參數(shù),所以既可以像前面那樣傳遞表達(dá)式,也可以傳遞用大括號(hào)包起來的代碼塊。

借助下面的被測函數(shù):

// divide.h  #pragma once  #include <stdexcept>     int divide(int dividend, int divisor) {   if(!divisor) {      throw std::length_error("can't be divided by 0"); // 故意的   }   return dividend / divisor;  }

測試程序如下:

// divide-unittest.cpp  #include <gtest/gtest.h>  #include "./divide.h"     TEST(Divide, ByZero) {   EXPECT_NO_THROW(divide(-1, 2));      EXPECT_ANY_THROW({      int k = 0;      divide(k, k);   });      EXPECT_THROW(divide(100000, 0), std::invalid_argument);  }

編譯運(yùn)行效果如下

C/C++中g(shù)test怎么用

容易想到,gtest的這些異常測試宏是用C++的try ... catch語句來實(shí)現(xiàn)的:

try {   statement;  }  catch(type const&) {   // throw  }  catch(...) {   // any throw  }  // no throw

如果把上圖中Visual C++的編譯選項(xiàng)/EHsc換成/EHa,try ... catch就可以同時(shí)支持C++風(fēng)格的異常和Windows系統(tǒng)的結(jié)構(gòu)化異常(SEH)。這樣,即使刪掉divide函數(shù)里的if判斷,測試代碼的EXPECT_ANY_THROW宏也會(huì)成功捕獲異常。

遺憾的是,目前僅使用這些測試宏無法得到獲得被拋出異常的詳細(xì)信息(如divide函數(shù)中的報(bào)錯(cuò)文本),這和gtest自身不愿意使用C++異常有關(guān)。

四、值參數(shù)化測試

有些時(shí)候,我們需要對(duì)代碼實(shí)現(xiàn)的功能使用不同的參數(shù)進(jìn)行測試,比如使用大量隨機(jī)值來檢驗(yàn)算法實(shí)現(xiàn)的正確性,或者比較同一個(gè)接口的不同實(shí)現(xiàn)之間的差別。gtest把“集中輸入測試參數(shù)”的需求抽象出來提供支持,稱為值參數(shù)化測試(Value Parameterized Test)。

值參數(shù)化測試包括4個(gè)步驟:

1.         從gtest的TestWithParam模板類派生一個(gè)類(記為C),模板參數(shù)為需要輸入的測試參數(shù)的類型。由于TestWithParam本身是從Test派生的,所以C就成了一個(gè)測試固件類。

2.         在C中,可以實(shí)現(xiàn)諸如SetUp、TearDown等方法。特別地,測試參數(shù)由TestWithParam實(shí)現(xiàn)的GetParam()方法依次返回。

3.         使用TEST_P(而不是TEST_F)定義測試。

4.         使用INSTANTIATE_TEST_CASE_P宏集中輸入測試參數(shù),它接受3個(gè)參數(shù):任意的文本前綴,測試類名(這里即為C),以及測試參數(shù)值序列。gtest框架依次使用這些參數(shù)值生成測試固件類實(shí)例,并執(zhí)行用戶定義的測試。

gtest提供了專門的模板函數(shù)來生成參數(shù)值序列,如下表所示:

參數(shù)值序列生成函數(shù)

含義

Bool()

生成序列{false, true}

Range(begin, end[, step])

生成序列{begin, begin+step, begin+2*step, ...} (不含end),step默認(rèn)為1

Values(v1, v2, ..., vN)

生成序列{v1, v2, ..., vN}

ValuesIn(container)ValuesIn(iter1, iter2)

枚舉STL container,或枚舉迭代器范圍[iter1, iter2)

Combine(g1, g2, ..., gN)

生成g1g2, ..., gN的笛卡爾積,其中g1g2, ..., gN均為參數(shù)值序列生成函數(shù)(要求C++0x的<tr1/tuple>

寫個(gè)小程序試一下。假設(shè)我們實(shí)現(xiàn)了一種快速累加算法,希望使用另一種直觀算法進(jìn)行正確性校驗(yàn)。算法實(shí)現(xiàn)和測試代碼如下

// addupto.h     #pragma once     inline unsigned NaiveAddUpTo(unsigned n) {      unsigned sum = 0;      for(unsigned i = 1; i <= n; ++i) sum += i;      return sum;  }     inline unsigned FastAddUpTo(unsigned n) {      return n*(n+1)/2;  }

測試程序如下:

// addupto_test.cpp     #include <gtest/gtest.h>  #include "addupto.h"     class AddUpToTest : public testing::TestWithParam<unsigned>  {  public:      AddUpToTest() { n_ = GetParam(); }  protected:      unsigned n_;  };     TEST_P(AddUpToTest, Calibration) {      EXPECT_EQ(NaiveAddUpTo(n_), FastAddUpTo(n_));  }     INSTANTIATE_TEST_CASE_P(      NaiveAndFast, // prefix      AddUpToTest,   // test case name      testing::Range(1u, 1000u) // parameters  );

注意TestWithParam的模板參數(shù)設(shè)置為unsigned類型,而在代碼倒數(shù)第2行,兩個(gè)常量值都加了u后綴來指定為unsigned類型。熟悉C++的讀者應(yīng)該知道,模板函數(shù)在進(jìn)行類型推斷(deduction)時(shí)匹配相當(dāng)嚴(yán)格,不像普通函數(shù)那樣允許類型提升(promotion)。如果上面省略u(píng)后綴,就會(huì)造成編譯錯(cuò)誤。當(dāng)然還可以顯式指定模板參數(shù):testing::Range<unsigned>(1, 1000)。

運(yùn)行效果如下,這里省略了開頭的大部分輸出(命令行窗口設(shè)置的緩沖區(qū)高度為3000行)。

C/C++中g(shù)test怎么用

感謝你能夠認(rèn)真閱讀完這篇文章,希望小編分享的“C/C++中g(shù)test怎么用”這篇文章對(duì)大家有幫助,同時(shí)也希望大家多多支持創(chuàng)新互聯(lián),關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道,更多相關(guān)知識(shí)等著你來學(xué)習(xí)!

文章名稱:C/C++中g(shù)test怎么用
瀏覽地址:http://www.rwnh.cn/article24/ghchje.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站設(shè)計(jì)公司、建站公司網(wǎng)站策劃、域名注冊(cè)、微信小程序

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)

成都網(wǎng)站建設(shè)公司
蚌埠市| 甘洛县| 罗城| 库车县| 三穗县| 临颍县| 社会| 遂昌县| 子长县| 瑞金市| 德州市| 成武县| 巫山县| 桂东县| 北海市| 阿鲁科尔沁旗| 铅山县| 舒兰市| 彩票| 七台河市| 万年县| 东山县| 凤城市| 永州市| 阿巴嘎旗| 柯坪县| 沅陵县| 苗栗市| 云梦县| 衡山县| 塔河县| 台州市| 麻栗坡县| 本溪市| 西乡县| 白城市| 平顶山市| 上蔡县| 延庆县| 鹤庆县| 图们市|