日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

Gtest 测试指导 入门基础(A)

發(fā)布時(shí)間:2023/12/14 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Gtest 测试指导 入门基础(A) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

Gtest 測(cè)試指導(dǎo) 入門(mén)基礎(chǔ)(A)
Table of Contents
? 1 Gtest的基本使用,包括下載,安裝,編譯。
o 1.1 下載
o 1.2 編譯
? 1.2.1 Gtest靜態(tài)庫(kù)的編譯
? 1.2.2 Gtest在VS中的編譯
? 2 在項(xiàng)目中配置Gtest
o 2.1 Gtest在非VS環(huán)境下的配置
o 2.2 Gtest在VS環(huán)境下的配置
? 3 Gtest的使用
o 3.1 Makefile
o 3.2 構(gòu)建代碼
o 3.3 Gtest斷言的使用
o 3.4 Gtest的異常檢查
o 3.5 Gtest的事件機(jī)制
o 3.6 Gtest的參數(shù)化
o 3.7 Gtest的死亡測(cè)試
? 3.7.1 *_DEATH(statement, regex)
? 3.7.2 *_EXIT(statement, predicate, regex)
? 3.7.3 死亡測(cè)試運(yùn)行方式
? 3.7.4 死亡測(cè)試的注意事項(xiàng)
o 3.8 Gtest的運(yùn)行參數(shù)
? 4 作業(yè)
o 4.1 編寫(xiě)一個(gè)DemoContainer類(lèi),按以下接口要求實(shí)現(xiàn):
? 5 參考文獻(xiàn)
1 Gtest的基本使用,包括下載,安裝,編譯。
1.1 下載
直接在google中搜索gtest,第一個(gè)就是。也可以從下面地址下載gtest。
https://code.google.com/p/googletest/downloads/
1.2 編譯
1.2.1 Gtest靜態(tài)庫(kù)的編譯
在下載解壓后,假設(shè)你把gtest源碼放在/usr/src/gtest
GTEST_DIR=/usr/src/gtest
設(shè)置完GTEST_DIR之后,執(zhí)行下列的命令
g++ -IGTESTDIR/include?I{GTEST_DIR}/include -IGTESTD?IR/include?I{GTEST_DIR} -c ${GTEST_DIR}/src/gtest-all.cc

ar -rv libgtest.a gtest-all.o
來(lái)生成libgtest.a。
1.2.2 Gtest在VS中的編譯
下載解壓后,里面有個(gè)msvc目錄,使用VS的同學(xué)可以直接的打開(kāi)msvc里面的工 程文件,打開(kāi)后會(huì)提示你升級(jí),升級(jí)后,我們直接編譯里面的“gtest”工程, 可以直接編過(guò)去的。最好是編譯Debug和Relese兩個(gè)版本。
這里需要注意的是:如果你升級(jí)gtest是在VS2008中升級(jí),那么你要使用 gtest 進(jìn)行測(cè)試的demo最好也是VS2008工程,不然你會(huì)發(fā)現(xiàn)很郁悶,你的 demo怎么也編不過(guò)。
如果你編譯了Debug和Relese兩個(gè)版本之后,在msvc里面就有兩個(gè)文件夾 Debug和Release,這兩個(gè)目錄中能看到編譯出來(lái)的gtestd.lib或gtest.lib文 件。
2 在項(xiàng)目中配置Gtest
2.1 Gtest在非VS環(huán)境下的配置

  • 把已經(jīng)生成的libgtest.a放在自己定義的lib中,如 h:/work/myGtest/lib.
  • 把Gtest需要的頭文件放在租戶(hù)定義的頭文件中,如: h:/work/myGtest/include(頭文件只需要從Gtest源碼中直接copy就可以了)
    2.2 Gtest在VS環(huán)境下的配置
    假設(shè)我們是用VS2010對(duì)gtest進(jìn)行的編譯,那么我們的這個(gè)例子也要在VS2010 中建立。
    創(chuàng)建我們要測(cè)試的Demo,在VS2010中創(chuàng)建一個(gè)空項(xiàng)目,命名為GtestMoney。 接下來(lái)為GtestMoney項(xiàng)目配置gtest環(huán)境。
  • 設(shè)置gtest頭文件路徑: 項(xiàng)目 - 屬性 - VC++目錄 - 包含目錄 - 編輯:在 這里添加你的gtest\include 例如我包含目錄是: D:\SoftWare\gtest-1.7.0\gtest-1.7.0\include
  • 設(shè)置gtest.lib路徑: 項(xiàng)目 - 屬性 - 鏈接器 - 輸入 - 附加依賴(lài)項(xiàng): 這里添加的你gtestd.lib/gtest.lib(Debug編譯模式用 gtestd.lib,Relese編譯用gtest.lib).例如我的附件依賴(lài)項(xiàng)是: D:\SoftWare\gtest-1.7.0\gtest-1.7.0\msvc\gtest\Debug\gtestd.lib
  • Runtime Library設(shè)置: 項(xiàng)目 - 屬性 - C/C++ - 代碼生成器 - 運(yùn)行庫(kù) 選擇 “多線程調(diào)試(/MTD)”。注意:如果Demo和gtest編譯用的都是 Relese版本,Runtime Library 設(shè)置為"/MT". 當(dāng)然你可以選擇動(dòng)態(tài)鏈接 (/MD),前提是你之前編譯的gtest也同樣使用了/MD選項(xiàng)。
    3 Gtest的使用
    下面將介紹在非VS環(huán)境下如何使用Gtest,我們將要用一個(gè)money的例子來(lái)展開(kāi) 對(duì)Gtest的學(xué)習(xí)。
    3.1 Makefile
    一般的項(xiàng)目要有一個(gè)頭文件一個(gè)cpp文件還有一個(gè)測(cè)試文件,我們分別命名為 Money.h, Money.cpp和MoneyTest.cpp.因?yàn)槲覀円褂玫紾test,所以添加一 個(gè)Makefile來(lái)連接Gtest到我們的工程中。Makefile的內(nèi)容如下。
  • Should change to your path which contain libgtest.a

    GTEST_DIR=H:/work/myGtest

    The dirtory which contain Money.h, Money.cpp, MoneyTest and Makefile

    SRC_DIR=/cygdrive/h/work/Sample

    LDFLAGS += -L(GTESTDIR)/lib?lgtest?lpthreadCXXFLAGS+=?c?g?Wall?Wextra?I(GTEST_DIR)/lib -lgtest -lpthread CXXFLAGS += -c -g -Wall -Wextra -I(GTESTD?IR)/lib?lgtest?lpthreadCXXFLAGS+=?c?g?Wall?Wextra?I(GTEST_DIR)/include

    TARGET = money_unittest
    OBJS = money.o gtestMoney.o

    CC=g++

    .PHONY: clean all test

    All Google Test headers. Usually you shouldn’t change this

    definition.

    all: $(TARGET)

    $(TARGET) : $(OBJS)
    $(CC) $^ -o $@ $(LDFLAGS)

    money.o : $(SRC_DIR)/Money.cpp $(SRC_DIR)/Money.h
    $(CC) $(CXXFLAGS) $< -o $@

    gtestMoney.o : $(SRC_DIR)/MoneyTest.cpp $(SRC_DIR)/Money.h
    $(CC) $(CXXFLAGS) $< -o $@

    clean:
    rm -f $(TARGET) $(OBJS)

    test: (TARGET)./(TARGET) ./(TARGET)./(TARGET)
    現(xiàn)在就可以在我們的Money工程中使用Gtest了。
    3.2 構(gòu)建代碼

  • 在我們開(kāi)發(fā)一個(gè)新的功能之前,首先我們要確定要"做什么"!比如說(shuō)我們 現(xiàn)在要實(shí)現(xiàn)一個(gè)money類(lèi),那我們就要首先確定我們這個(gè)money類(lèi)都需要具 備哪些功能和屬性。當(dāng)我們提到money:
  • 首先想到的是money的數(shù)量(amount);
  • 還會(huì)想到money的貨幣種類(lèi)(currency),是美元還是人民幣;
  • money與money之間會(huì)有比較:這兩個(gè)money的數(shù)量(amount)和貨幣種類(lèi) (currency)是否相等(有 == 和 != 兩種可能);
  • 兩個(gè)money如果貨幣種類(lèi)相同,那么兩個(gè)money的數(shù)量就可以相加。
  • 當(dāng)我們確定功能(money)之后要寫(xiě)針對(duì)這個(gè)功能(還沒(méi)有具體的代碼的 money類(lèi))寫(xiě)單元測(cè)試?yán)?。單元測(cè)試?yán)右采w這個(gè)功能(money)的"做什 么"。每個(gè)單元測(cè)試至少應(yīng)該有兩個(gè)測(cè)試列子,一個(gè)是Negative,一個(gè)是 positive。
    首先我們就要開(kāi)始寫(xiě)一個(gè)測(cè)試用例來(lái)測(cè)試我們的money能否實(shí)例化成功。
    // file:MoneyTest.cpp
  • TEST(MoneyConstructorTest, TestConstructor)
    {
    // Set up
    const std::string currencyAA(“AA”);
    const double longNumber = 123.456;

    // Process Money money(longNumber, currencyAA);// Check // Positive test case EXPECT_EQ(longNumber, money.getAmount()); EXPECT_STREQ("AA", money.getCurrency().c_str());

    }

    int main(int argc, char** argv)
    {
    return 0;
    }
    這段測(cè)試代碼是測(cè)試一個(gè)實(shí)例money是否創(chuàng)建成功,money的amount和currency是 否與我們創(chuàng)建實(shí)例初始化的值是相同的。
    而此時(shí)執(zhí)行命令"make"進(jìn)行編譯肯定報(bào)錯(cuò),因?yàn)槲覀冞€沒(méi)有Money這個(gè)類(lèi)也沒(méi)有接 口函數(shù)getAmount()和getCurrency()。所以我們要根據(jù)測(cè)試用例來(lái)補(bǔ)充我們的 Money類(lèi)。
    根據(jù)測(cè)試用例我們知道,Money類(lèi)要有一個(gè)getAmount()這個(gè)功能要得到成員 amount。還有一個(gè)getCurrency()得到成員currency,而成員amount和currency通 過(guò)Money的構(gòu)造函數(shù)進(jìn)行初始化。所以接下來(lái)在我們的代碼中實(shí)現(xiàn)這部分功能。
    //file:Money.h

    #ifndef MONEY_H
    #define MONEY_H

    #include
    #include

    class Money
    {
    public:
    Money( double amount, std::string currency )
    : m_amount( amount )
    , m_currency( currency )
    {
    }
    double getAmount() const;
    std::string getCurrency() const;

    private:
    double m_amount;
    std::string m_currency;
    };
    #endif
    // file Money.cpp

    #include “Money.h”

    double Money::getAmount() const
    {
    return m_amount;
    }

    std::string Money::getCurrency() const
    {
    return m_currency;
    }
    這時(shí)編譯(make)還是編譯不過(guò),因?yàn)槲覀儧](méi)有運(yùn)行所有的測(cè)試用例。那我們用什 么運(yùn)行測(cè)試呢?在MoneyTest.cpp的main函數(shù)中添加"RUN_ALL_TESTS()"意思是: 運(yùn)行所有測(cè)試案例。
    // file MoneyTest.cpp
    int main(int argc, char** argv)
    {

    return RUN_ALL_TESTS();

    }
    這個(gè)時(shí)候編譯(make)就會(huì)通過(guò)。但是執(zhí)行的時(shí)候(make test)會(huì)產(chǎn)生下面的錯(cuò)誤:
    lixiang@lixiang-PC /cygdrive/h/work/Sample
    $ make test
    ./money_unittest

    This test program did NOT call ::testing::InitGoogleTest before calling RUN_ALL_
    TESTS(). Please fix it.
    Makefile:36: recipe for target ‘test’ failed
    make: *** [test] Error 1

    通過(guò)錯(cuò)誤我們可以看到需要在MoneyTest.cpp的main函數(shù)中加入 testing::InitGoogleTest 所以我們需要繼續(xù)修改MoneyTest.cpp中的main:
    // file MoneyTest.cpp
    int main(int argc, char** argv)
    {
    testing::InitGoogleTest(&argc, argv);
    return RUN_ALL_TESTS();
    }
    這時(shí)我們make編譯成功。運(yùn)行money_unittest.exe會(huì)有如下輸出:
    好,到目前為止我們已經(jīng)完成了Gtest的環(huán)境的搭配和基本的構(gòu)建使用。下面就來(lái) 具體的學(xué)習(xí)一下Gtest針對(duì)不同情況的測(cè)試吧。
    3.3 Gtest斷言的使用
    上面就是一個(gè)簡(jiǎn)單的測(cè)試案例。這個(gè)我們使用了TEST這個(gè)gtest包裝好的宏, 它有兩個(gè)參數(shù),官方的解釋:#define TEST(test_case_name, test_name) GTEST_TEST(test_case_name, test_name)。
    對(duì)檢查點(diǎn)的檢查,我們上面使用到了EXPECT_EQ和EXPECT_STREQ這兩個(gè)宏, 其中EXPECT_EQ這個(gè)宏用來(lái)比較兩個(gè)數(shù)值是否相等。 EXPECT_STREQ(expected_str, actual_str)是比較兩個(gè)C字符串內(nèi)容(同時(shí) 支持char* 和 wchar_t*).
    Gtest采用了大量的宏來(lái)包裝斷言,此斷言不同于C語(yǔ)言的斷言(assert),按照 使用方法分為兩類(lèi):

  • EXPECT_* 系列斷言失敗時(shí),案例繼續(xù)往下執(zhí)行。

  • ASSERT_* 系列斷言失敗時(shí),退出當(dāng)前函數(shù),ASSERT_*后面的代碼不會(huì)被 執(zhí)行.(注意:并不是退出當(dāng)前案例)
    在上面的列子中為了我們的案例能夠運(yùn)行起來(lái)我們?cè)趍ain函數(shù)中添加如下代 碼:
    testing::InitGoogleTest(&argc, argv);
    因?yàn)間test的測(cè)試用例允許接收一系列的命令行參數(shù)因此我們?cè)?"testing::InitGoogleTest(&argc, argv);"中將命令行參數(shù)傳給gtest, gtest的命令行參數(shù)非常的豐富,有興趣的大家可以自己查閱資料詳細(xì)的了解 一下。
    下面我們添加一個(gè)新的斷言:
    // file: MoneyTest.cpp
    TEST(MoneyConstructorTest, TestConstructor)
    {
    // Set up
    const std::string currencyAA(“AA”);
    const double longNumber = 123.456;

    // Process
    Money money(longNumber, currencyAA);

    // Check
    EXPECT_EQ(longNumber, money.getAmount());
    EXPECT_STREQ(“AA”, money.getCurrency().c_str());

    EXPECT_EQ(555, money.getAmount());

    std::cout << “Code after EXPECT!” << std::endl;
    }
    會(huì)出現(xiàn)什么結(jié)果呢?

  • 這樣的結(jié)果將會(huì)產(chǎn)生!這是因?yàn)镋XPECT_EQ第一個(gè)參數(shù)是我們期望的結(jié)果是數(shù)值 555,而實(shí)際的結(jié)果是123.456,這與我們的期望不同,所以會(huì)有error產(chǎn)生。
    值得注意的是在"EXPECT_EQ(555, money.getAmount())“出現(xiàn)error之后仍然繼 續(xù)執(zhí)行輸出"Code after EXPECT!”.
    如果我們期望結(jié)果數(shù)值不是實(shí)際函數(shù)的結(jié)果數(shù)值,那么就用下面的語(yǔ)句。
    EXPECT_NE(555, money.getAmount());
    這個(gè)時(shí)候所有的測(cè)試就會(huì)通過(guò)了!
    讓我們?cè)偌由弦粋€(gè)ASSERT_*系列的斷言,來(lái)體會(huì)ASSERT與EXPECT區(qū)別。
    // file MoneyTest.cpp

    // Assert test
    TEST(MoneyConstructorTest, TestConstructorAssert)
    {
    // Set up
    const std::string currencyBB(“ASSERT”);
    const double longNumber = 222.222;

    // Process Money money(longNumber, currencyBB);// Check ASSERT_STREQ("AA", money.getCurrency().c_str());std::cout << "Code after ASSERT!" << std::endl;

    }

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

    在ASSERT失敗之后, 語(yǔ)句"Code after ASSERT"沒(méi)有出現(xiàn)! 所以我們注意,最好不要在ASSERT語(yǔ)句后面做釋放內(nèi)存等操作!
    現(xiàn)在我們只是依照Money的功能和功能對(duì)應(yīng)的測(cè)試用例添加了Money類(lèi)的構(gòu)造函數(shù) 和接口getAmount(), getCurrency的源碼,剩下的接口分別是operator ==, operator != 和 operator +=,大家可以按照想好功能,為功能添加測(cè)試用例, 補(bǔ)充功能源碼的方式來(lái)完成對(duì)以上三個(gè)未完成的接口的測(cè)試。下面是參考代碼:
    // file Money.h

    #ifndef MONEY_H
    #define MONEY_H

    #include
    #include

    class IncompatibleMoneyError : public std::runtime_error
    {
    public:
    IncompatibleMoneyError() : std::runtime_error( “Incompatible moneys” )
    {
    }
    };

    class Money
    {
    public:
    Money( double amount, std::string currency )
    : m_amount( amount )
    , m_currency( currency )
    {
    }

    double getAmount() const;

    std::string getCurrency() const;

    bool operator ==( const Money &other ) const;

    bool operator !=( const Money &other ) const;

    Money &operator +=( const Money &other );

    private:
    double m_amount;
    std::string m_currency;
    };
    #endif
    // file Money.cpp

    #include “Money.h”

    double Money::getAmount() const
    {
    return m_amount;
    }

    std::string Money::getCurrency() const
    {
    return m_currency;
    }

    bool Money::operator ==( const Money &other ) const
    {
    return m_amount == other.m_amount &&
    m_currency == other.m_currency;
    }

    bool Money::operator !=( const Money &other ) const
    {
    return !(*this == other);
    }

    Money & Money::operator +=( const Money &other )
    {
    if ( m_currency != other.m_currency )
    throw IncompatibleMoneyError();

    m_amount += other.m_amount; return *this;

    }

    大家都可以用EXPECT_TRUE(FALSE)/ASSERT_TRUE(FALSE)書(shū)寫(xiě)出對(duì)這些函數(shù)接口 的測(cè)試相應(yīng)的測(cè)試。
    gtest的斷言按照常用功能依次分為12類(lèi),平常主要用到的是一下幾類(lèi):
    |ASSERT_FALSE(condition) |EXPECT_TRUE(condition) |condition == false | |ASSERT_NE(val1, val2) | EXPECT_NE(val1, val2) | val1 != val2 |
    布爾值比較
    ASSERT_TRUE(condition) EXPECT_TRUE(condition) condition == true
    數(shù)值型數(shù)據(jù)比較
    ASSERT_EQ(expected, actual) EXPECT_EQ(expected, actual) expected == actual
    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) val2 >= val2
    字符串比較
    ASSERT_STREQ(str1, str2) EXPECT_STREQ(str1, str2) 兩個(gè)C字符串內(nèi)容相同(同時(shí)支持char *和wchart *類(lèi)型)
    ASSERT_STRNE(str1, str2) EXPECT_STRNE(str1, str2) 兩個(gè)C字符串內(nèi)容不同(同時(shí)支持char *和wchart *類(lèi)型)
    ASSERT_STRCASEEQ(str1,str2) EXPECT_STRCASEEQ(str1,str2) 兩個(gè)C字符串內(nèi)容相同,忽略大小寫(xiě)(只支持char *類(lèi)型)
    ASSERT_STRCASENE(str1,str2) EXPECT_STRCASENE(str1,str2) 兩個(gè)C字符串內(nèi)容不同,忽略大小寫(xiě)(只支持char *類(lèi)型)
    浮點(diǎn)數(shù)比較
    ASSERT_FLOAT_EQ(val1,val2) EXPECT_FLOAT_EQ(val1,val2) the two float values are almost equal
    ASSERT_DOUBLE_EQ(val1,val2) EXPECT_DOUBLE_EQ(val1,val2) the two double values are almost equal
    近似數(shù)比較
    ASSERT_NEAR(val1, val2, abs_error) EXPECT_NEAR(val1, val2, abs_error 兩個(gè)數(shù)值val1和val2的 絕對(duì)值差不超過(guò) abs_error
    異常檢查
    ASSERT_THROW(statement, exception_type) EXPECT_THROW(statement, exception_type) 拋出指定類(lèi)型異常
    ASSERT_THROW(statement) EXPECT_THROW(statement) 拋出任意類(lèi)型異常
    ASSERT_NO_THROW(statement) EXPECT_NO_THROW(statement) 不拋異常
    函數(shù)值與參數(shù)檢查(目前最多只支持5個(gè)參數(shù))
    ASSERT_PRED1(pred1, val1) EXPECT_PRED1(pred1, val1) pred1(val1) returns true
    ASSERT_PRED2(pred2, val1,val2) EXPECT_PRED2(pred2, val1, val2) pred2(val1, val2) returns true
    Windows HRESULT
    ASSERT_HRESULT_SUCCEEDED (expression) EXPECT_HRESULT_SUCCEEDED (expression) expression is a success HRESULT
    ASSERT_HRESULT_FAILED (expression) EXPECT_HRESULT_FAILED (expression) expression is a failure HRESUL
    自定義格式函數(shù)與參數(shù)檢查(目前最多支持5個(gè)參數(shù))
    ASSERT_PRED_FORMAT1(pred1, val1) EXPECT_PRED_FORMAT1(pred1, val1) pred1(val1) is successful
    ASSERT_PRED_FORMAT1(pred1, val1, val2) EXPECT_PRED_FORMAT1(pred1, val1, val2) pred2(val1, val2) is successful
    3.4 Gtest的異常檢查
    通過(guò)上面的表格我們知道gtest能夠檢測(cè)異常狀態(tài),異常檢查一般用到的是 ASSERT_THROW/EXPECT_THROW。那么我們就來(lái)增加一個(gè)異常檢查的測(cè)試。
    // file MoneyTest.cpp

    TEST(MoneyThrowTest, ThrowTest)
    {
    // Set up
    const Money money123AA(123, “AA”);

    // Process Money money123BB(123, "BB");EXPECT_ANY_THROW(money123BB += money123AA); EXPECT_THROW(money123BB += money123AA, IncompatibleMoneyError);

    }
    那么現(xiàn)在的輸出結(jié)果是:

    MoneyThrowTest.ThrowTest顯示的狀態(tài)是通過(guò),證明已經(jīng)有異常拋出,測(cè)試用例 通過(guò)。
    3.5 Gtest的事件機(jī)制
    在開(kāi)始gtest的事件機(jī)制之前,我們需要了解一個(gè)概念:測(cè)試固件!
    很多時(shí)候,我們想在不同的測(cè)試執(zhí)行前創(chuàng)建相同的配置環(huán)境,在測(cè)試執(zhí)行結(jié)束后 執(zhí)行相應(yīng)的清理工作,測(cè)試固件(Test Fixture)為這種需求提供了方便。在單 元測(cè)試中,Fixture的作用是為測(cè)試創(chuàng)建輔助性的上下文環(huán)境,實(shí)現(xiàn)測(cè)試的初始化 和終結(jié)與測(cè)試過(guò)程本身的分離,便于不同測(cè)試使用相同代碼來(lái)搭建固定的配置環(huán) 境。用體操比賽的說(shuō)法,測(cè)試過(guò)程體現(xiàn)了特定測(cè)試的自選動(dòng)作,測(cè)試固件則體現(xiàn) 了對(duì)一系列測(cè)試(在開(kāi)始和結(jié)束時(shí))的規(guī)定動(dòng)作。有些講單元測(cè)試的書(shū)籍直接把 測(cè)試固件稱(chēng)為Scaffolding(腳手架)。使用測(cè)試固件比單純調(diào)用TEST宏稍微麻煩 一些:

  • 從gtest的testing::Test類(lèi)派生一個(gè)類(lèi),用public或protected定義 以下所有成員。
  • (可選)建立環(huán)境:使用默認(rèn)構(gòu)造函數(shù),或定義一個(gè)虛成員函數(shù) virtual void SetUp()。
  • (可選)銷(xiāo)毀環(huán)境:使用析構(gòu)函數(shù),或定義一個(gè)虛成員函數(shù)virtual void TearDown()。
  • 用TEST_F定義測(cè)試,寫(xiě)法與TEST相同,但測(cè)試用例名必須為上面定義 的類(lèi)名。
    每個(gè)帶固件的測(cè)試的執(zhí)行順序是:
  • 調(diào)用默認(rèn)構(gòu)造函數(shù)創(chuàng)建一個(gè)新的帶固件對(duì)象。
  • 立即調(diào)用SetUp函數(shù)。
  • 運(yùn)行TEST_F體。
  • 立即調(diào)用TearDown函數(shù)。
  • 調(diào)用析構(gòu)函數(shù)銷(xiāo)毀類(lèi)對(duì)象。
    Gtest提供了多種事件機(jī)制方便在測(cè)試用例之前或者完成以后進(jìn)行一些操作,
    通過(guò)這些操作,我們可以在各個(gè)測(cè)試用例之前共享一些通用方法,共享資源。使 我們的用例更加的簡(jiǎn)潔,清晰。Gtest的事件機(jī)制按照使用方法分為3類(lèi):
  • 全局事件:在所有測(cè)試用例執(zhí)行之前和完成之后生效??梢栽谌质录型瓿?一些測(cè) 試環(huán)境的初始化和資源回收工作,比如預(yù)留內(nèi)存申請(qǐng)/回收,組件對(duì)象 初始化/析構(gòu)等。 注意: 資源的初始化放在SetUp()中。資源的回收放在TearDown()中。
  • TestSuite級(jí)別:在指定的測(cè)試套第一個(gè)測(cè)試用例之前,最后一個(gè)測(cè)試用例之 后。如果根據(jù)子模塊定義測(cè)試套,那么就可以在TestSuite事件中完成一些子 模塊的線程、消息隊(duì)列等的初始化和資源回收工作。
  • TestCase級(jí)別:在每個(gè)測(cè)試用例執(zhí)行前后,即在每個(gè)測(cè)試代碼的斷言前后進(jìn)行 執(zhí)行。
    下面我們就分別介紹這3類(lèi)事件的用法:
    ? 全局事件
    必須通過(guò)繼承testing::Environment類(lèi),實(shí)現(xiàn)里面的SetUp和TearDown方 法:
  • SetUp()方法在所有用例執(zhí)行前執(zhí)行;
  • TearDown()方法在所有用例執(zhí)行后執(zhí)行;
    在我們的MoneyTest.cpp中添加一個(gè)此事件的代碼是:
    // file MoneyTest.cpp
  • class MoneyTestEnvironment : public testing::Environment
    {
    public:
    virtual void SetUp()
    {
    std::cout << “Money Golbal Event SetUp.” << std::endl;
    }

    virtual void TearDown() {std::cout << "Money Global Event TearDown" << std::endl; }

    };
    完成繼承類(lèi)方法實(shí)現(xiàn)以后,還需要告訴gtest添加全局事件,我們需要在main函數(shù) 中通過(guò)testing::AddGlobalTestEnvironment方法添加該全局事件。如果需要增加 全局事件,也可以寫(xiě)多個(gè)繼承類(lèi),然后將事件都添加到測(cè)試用例之前。
    int main(int argc, char** argv)
    {
    // Add the global test environment
    testing::AddGlobalTestEnvironment(new MoneyTestEnvironment);

    testing::InitGoogleTest(&argc, argv);return RUN_ALL_TESTS();

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

    從結(jié)果中我們可以看到Setup()在所有測(cè)試用例開(kāi)始之前就自動(dòng)被調(diào)用,而 TearDown()是在所有測(cè)試用例執(zhí)行之后被調(diào)用。所以一些全局的資源初始化放在 SetUp()中,全局的資源回收放在TearDown()中。
    ? TestSuite事件
    在某些情況下,我們可能不需要在整個(gè)全局的范圍內(nèi)有一些共享而需要在各個(gè)測(cè) 試間共享一個(gè)相同的環(huán)境來(lái)保存和傳遞狀態(tài),或者環(huán)境的狀態(tài)是只讀的,可以只 初始化一次,再或者創(chuàng)建環(huán)境的過(guò)程開(kāi)銷(xiāo)很高,要求只初始化一次。共享某個(gè)固 件環(huán)境的所有測(cè)試合稱(chēng)為一個(gè)“測(cè)試套件”(Test Suite),gtest中利用靜態(tài)成 員變量和靜態(tài)成員函數(shù)實(shí)現(xiàn)這個(gè)概念:

  • (可選)在testing::Test的派生類(lèi)中,定義若干靜態(tài)成員變量來(lái)維 護(hù)套件的狀態(tài)。
  • (可選)建立共享環(huán)境:定義一個(gè)靜態(tài)成員函數(shù)static void SetUpTestCase()。
  • (可選)銷(xiāo)毀共享環(huán)境:定義一個(gè)靜態(tài)成員函數(shù)static void TearDownCase()。
    特別注意:
  • SetUpTestCase()方法在TestSuit的第一個(gè)TestCase之前執(zhí)行;
  • TearDownTestCase()方法在TestSuite的最后一個(gè)TestCase之后執(zhí)行;
    在MoneyTest.cpp中添加TestSuite事件的代碼如下:
    // file MoneyTest.cpp
  • // Test Suite Event Test
    class MoneySuiteEventTest : public testing::Test
    {
    public:
    static void SetUpTestCase()
    {
    std::cout << “Money Test SuiteEventTest SetUpTestCase.” << std::endl;
    }

    static void TearDownTestCase() {std::cout << "Money Test SuiteEventTest TearDownTestCase." << std::endl; }

    };

    TEST_F(MoneySuiteEventTest, SuiteTestCaseOne)
    {
    const std::string currencyCC(“SuiteTestCaseOne”);
    const double longNumber = 123.456;

    // Process Money money(longNumber, currencyCC);// Check EXPECT_EQ(longNumber, money.getAmount()); EXPECT_STREQ("SuiteTestCaseOne", money.getCurrency().c_str());

    }

    TEST_F(MoneySuiteEventTest, SuiteTestCaseTwo)
    {
    const std::string currencyCC(“SuiteTestCaseTwo”);
    const double longNumber = 123.456;

    // Process Money money(longNumber, currencyCC);// Check EXPECT_EQ(longNumber, money.getAmount()); EXPECT_STREQ("SuiteTestCaseTwo", money.getCurrency().c_str());

    }
    特別注意使用TEST_F宏的第一個(gè)參數(shù)必須是上面繼承testing::test的繼承類(lèi)名字 (MoneySuiteEventTest)。
    運(yùn)行的結(jié)果是:

    從輸出可以看出SetUpTestCase()是在SuitTestCaseOne之前調(diào)用而 TearDownTestCase()是在SuiteTestCaseTwo后調(diào)用。
    ? TestCase事件
    與TestSuite事件實(shí)現(xiàn)方法相同,需要通過(guò)繼承testing::Test類(lèi),但是只需 要實(shí)現(xiàn)里面的SetUp和TearDown兩個(gè)方法

  • SetUp()方法在每個(gè)TestCase之前執(zhí)行
  • TearDown()方法在每個(gè)TestCase之后執(zhí)行;
    在MonyTest.cpp中TestCase事件的代碼是:
    // file MoneyTest.cpp
  • // Test TestCase
    class MoneyTestCaseTest : public testing::Test
    {
    public:
    void SetUp()
    {
    std::cout << “Money Test MoneyTestCaseTest SetUp.” << std::endl;
    }

    void TearDown() {std::cout << "Money Test MoneyTestCaseTest TearDown." << std::endl; }

    };

    TEST_F(MoneyTestCaseTest, TestCaseTestOne)
    {
    const std::string currencyDD(“TestCaseTestOne”);
    const double longNumber = 123.456;

    // Process Money money(longNumber, currencyDD);// Check EXPECT_EQ(longNumber, money.getAmount());

    }

    TEST_F(MoneyTestCaseTest, TestCaseTestTwo)
    {
    const std::string currencyDD(“TestCaseTestTwo”);
    const double longNumber = 123.456;

    // Process Money money(longNumber, currencyDD);// Check EXPECT_EQ(longNumber, money.getAmount());

    }
    運(yùn)行的結(jié)果是

    3.6 Gtest的參數(shù)化
    在設(shè)計(jì)測(cè)試案例時(shí),經(jīng)常需要考慮給被測(cè)函數(shù)傳入不同的值的情況,以前的做 法一般是寫(xiě)一個(gè)通用方法,然后編寫(xiě)在測(cè)試案例調(diào)用它,即使使用了通用方法, 也需要很多重復(fù)性的工作。以下是一般的測(cè)試方法,如果需要測(cè)試N個(gè)數(shù)字, 則需要拷貝復(fù)制粘貼N次.
    Gtest在這里提供了一個(gè)靈活的函數(shù)參數(shù)化測(cè)試的方案:

  • 告訴gtest參數(shù)類(lèi)型:必須添加一個(gè)繼承類(lèi)testing::TestWithParam, 其中T就是需 要參數(shù)化的參數(shù)類(lèi)型。以上面為例,需要參數(shù)化一個(gè)int型 的參數(shù);
  • 參數(shù)類(lèi)型確定以后,需要使用一個(gè)新的宏TSET_P進(jìn)行測(cè)試用例,在 TEST_P宏里,使 用GetParam()方法獲取當(dāng)前的參數(shù)的具體值;
  • 使用INSTANTIATE_TEST_CASE_P宏來(lái)確定測(cè)試的參數(shù)取值范圍.其中第 一個(gè)參數(shù)是測(cè)試用例的前綴,可以任意取,第二個(gè)參數(shù)是測(cè)試案例的名稱(chēng), 需要和之前定義的參數(shù)化的類(lèi)的名字相同。第三個(gè)參數(shù)可以理解成參數(shù)生 產(chǎn)器。
    在MoneyTest.cpp中Gtest的參數(shù)化代碼是:
    // file MoneyTest.cpp
  • // Parameter Testing one
    class MoneyParameterTest : public testing::TestWithParam
    {
    public:
    };

    TEST_P(MoneyParameterTest, ParameterTest)
    {
    double acount = GetParam();
    Money money(acount, “Test”);
    EXPECT_EQ(acount, money.getAmount());
    }

    INSTANTIATE_TEST_CASE_P(ParameterTest, MoneyParameterTest,
    testing::Values(111.111, 222.2222, 333.3333, 444.44444));
    運(yùn)行的結(jié)果是:

    Gtest中除了上面testing::Values()數(shù)據(jù)生成器之外,還有一系列的參數(shù)生成器:
    Gtest中的參數(shù)生成器
    Range(begin, end[, step]) 范圍在begin~end之間,步長(zhǎng)為step,不包括end
    Values(v1, v2, …, vN) v1,v2到vN的值
    ValuesIn(container) and ValuesIn(begin, end) 從一個(gè)C類(lèi)型的數(shù)組或是STL容器,或是迭代器中取值
    Bool() 取false 和 true 兩個(gè)值
    Combine(g1, g2, …, gN) 這個(gè)比較強(qiáng)悍,它將g1,g2,…gN進(jìn)行排列組合,g1,g2,…gN本身是一個(gè)參數(shù)生成器,每次分別從g1,g2,…gN中各取出一個(gè)值,組合成一個(gè)元組(Tuple)作為一個(gè)參數(shù)。說(shuō)明:這個(gè)功能只在提供了<tr1/tuple>頭的系統(tǒng)中有效。gtest會(huì)自動(dòng)去判斷是否支持tr/tuple,如果你的系統(tǒng)確實(shí)支持,而gtest判斷錯(cuò)誤的話,你可以重新定義宏GTEST_HAS_TR1_TUPLE=1。
    除了測(cè)試用例可以參數(shù)化以外,gtest還提供了針對(duì)各種不同類(lèi)型數(shù)據(jù)時(shí)的方案, 以及參數(shù)化類(lèi)型的方案

  • 首先需要定義一個(gè)模版類(lèi),從testing::Test類(lèi)繼承
  • 然后再定義需要測(cè)試的具體數(shù)據(jù)類(lèi)型,比如下面定義了測(cè)試char, int和 unsigned int類(lèi)型;
  • 又是一個(gè)新的宏,來(lái)完成我們的測(cè)試案例,在聲明模版的數(shù)據(jù)類(lèi)型時(shí),使用 TypeParam
    // file: MoneyTest.cpp
  • // Parameter Testing two

    // Step one
    template
    class MoneyTemplateTest : public testing::Test
    {
    public:
    typedef std::list List;
    static T shared;
    T value;
    };

    // Step two
    typedef testing::Types<double, long double> MoneyTypes;
    TYPED_TEST_CASE(MoneyTemplateTest, MoneyTypes);

    // Step three
    TYPED_TEST(MoneyTemplateTest, TemplateTest)
    {
    // Inside a test, refer to the special name TypeParam to get the type
    // parameter. Since we are inside a derived class template, C++ requires
    // us to visit the members of MoneyTemplateTest via ‘this’.
    TypeParam n = this->value;

    // To refer to typedefs in the fixture, add the 'typename TestFixture::' // prefix. The 'typename' is required to satisfy the compiler. typename TestFixture::List values; values.push_back(n);

    }

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

    3.7 Gtest的死亡測(cè)試
    “死亡測(cè)試”名字比較恐怖,這里的“死亡”是指程序的崩潰。通常在測(cè)試過(guò) 程中,我們需要考慮各種各樣的輸入,有的輸入可能直接導(dǎo)致程序崩潰,這時(shí) 我們就需要檢查程序是否按照預(yù)期的方式掛掉,這也就是所謂的“死亡測(cè)試”。 gtest的死亡測(cè)試能做到在一個(gè)安全的環(huán)境下執(zhí)行崩潰的測(cè)試案例,同時(shí)又對(duì) 崩潰結(jié)果進(jìn)行驗(yàn)證
    死亡測(cè)試宏定義
    ASSERT_DEATH(statement, regex) EXPECT_DEATH(statement, regex) statement crashes with the given error
    ASSERT_EXIT(statement, predicate, regex) EXPECT_EXIT(statement, predicate, regex) statement exits with the given error and its exit code matches predicate
    3.7.1 _DEATH(statement, regex)
    由于有些異常只在Debug下拋出,因此還提供了_DEBUGDEATH,用來(lái)處理 Debug和Realease下的不同。 簡(jiǎn)單來(lái)說(shuō),通過(guò)*_DEATH(statement, regex) 和*_EXIT(statement, predicate, regex),我們可以非常方便的編寫(xiě)導(dǎo)致崩潰 的測(cè)試案例,并且在不影響其他案例執(zhí)行的情況下,對(duì)崩潰案例的結(jié)果進(jìn)行檢 查。 以下是*DEATH用法介紹:

  • statement是被測(cè)試的代碼語(yǔ)句,這里可以使用表達(dá)式,也可以直接調(diào)用函 數(shù)結(jié)果;
  • regex是一個(gè)正則表達(dá)式,用來(lái)匹配異常時(shí)在stderr中輸出的內(nèi)容;
  • 編寫(xiě)死亡測(cè)試案例時(shí),TEST的第一個(gè)參數(shù),即testcase_name,請(qǐng)使用 DeathTest后綴。 原因是gtest會(huì)優(yōu)先運(yùn)行死亡測(cè)試案例,應(yīng)該是為線程安 全考慮。
    // file: MoneyTest.cpp
  • // Death Test
    TEST(MoneyDeathTest, DeathTest)
    {
    // Set up
    Money moneyAA(123.456, “DeathTestOne”);
    Money moneyBB(0.123456, “DeathTestTwo”);

    // Process EXPECT_DEATH(moneyAA+=moneyBB ,"Test MoneyDeathTest");

    }
    死亡測(cè)試的結(jié)果是:

    從運(yùn)行的結(jié)果我們可以看到"死亡測(cè)試"是第一個(gè)被執(zhí)行的測(cè)試!
    3.7.2 *_EXIT(statement, predicate, regex)
    ? 1. statement
    ? 2. predicate 在這里必須是一個(gè)委托,接收int型參數(shù),并返回bool。只有當(dāng)返回值為true時(shí),死亡測(cè)試案例才算通過(guò)。
    gtest提供了一些常用的predicate:

  • testing::ExitedWithCode(exit_code) : 如果程序正常退出并且退出碼與 exit_code相同則返回true。
  • testing::KilledBySignal(signal_number) // Windows下不支持 :如果 程序被signal_number信號(hào)kill的話就返回true
    ? 3. regex是一個(gè)正則表達(dá)是,用來(lái)匹配異常時(shí)在stderr中輸出的內(nèi)容。
    在POSIX系統(tǒng)(Linux, Cygwin, 和 Mac)中,gtest的死亡測(cè)試中使用的是 POSIX風(fēng)格的正則表達(dá)式,想了解POSIX風(fēng)格表達(dá)式可參考:
  • POSIX extended regular expression
  • Wikipedia entry:
    在Windows系統(tǒng)中,gtest的死亡測(cè)試中使用的是gtest自己實(shí)現(xiàn)的簡(jiǎn)單的正 則表達(dá)式語(yǔ)法。 相比POSIX風(fēng)格,gtest的簡(jiǎn)單正則表達(dá)式少了很多內(nèi)容, 比如 (“x|y”), ("(xy)"), ("[xy]") 和(“x{5,7}”)都不支持。
    3.7.3 死亡測(cè)試運(yùn)行方式
    ? 1. fast方式(默認(rèn)方式)
  • ? testing::FLAGS_gtest_death_test_style = “fast”;
    ? threadsafe方式

    ? testing::FLAGS_gtest_death_test_style = “threadsafe”;
    你可以在 main() 里為所有的死亡測(cè)試設(shè)置測(cè)試形式,也可以為某次測(cè)試單 獨(dú)設(shè)置。Google Test會(huì)在每次測(cè)試之前保存這個(gè)標(biāo)記并在測(cè)試完成后恢復(fù), 所以你不需要去管這部分工作 。如:
    int main(int argc, char** argv)
    {
    // Add the global test environment
    testing::AddGlobalTestEnvironment(new MoneyTestEnvironment);

    testing::InitGoogleTest(&argc, argv);testing::FLAGS_gtest_death_test_style = "fast";return RUN_ALL_TESTS();

    }
    3.7.4 死亡測(cè)試的注意事項(xiàng)

  • 不要在死亡測(cè)試?yán)镝尫艃?nèi)存。
  • 在父進(jìn)程里再次釋放內(nèi)存。
  • 不要在程序中使用內(nèi)存堆檢查。
    3.8 Gtest的運(yùn)行參數(shù)
    使用gtest編寫(xiě)的測(cè)試案例通常本身就是一個(gè)可執(zhí)行文件,因此運(yùn)行起來(lái)非常 方便。同時(shí),gtest也為我們提供了一系列的運(yùn)行參數(shù)(環(huán)境變量、命令行參 數(shù)或代碼里指定),使得我們可以對(duì)案例的執(zhí)行進(jìn)行一些有效的控制。gtest 提供了三種設(shè)置的途徑:
  • 系統(tǒng)環(huán)境變量
  • 命令行參數(shù)
  • 代碼中指定FLAG
    其優(yōu)先級(jí)原則是,最后設(shè)置的那個(gè)會(huì)生效。通常情況下的優(yōu)先級(jí)順序?yàn)?#xff1a; 命令行參數(shù) > 代碼中指定FLAG > 系統(tǒng)環(huán)境變量。由于在gtest工程main函數(shù) 中,gtest通過(guò)testing::InitGoogleTest方法直接處理輸入?yún)?shù),因此測(cè)試用 例可以處理命令行參數(shù)。
    代碼:
    // MoneyTest.cpp
  • int main(int argc, char** argv)
    {
    // Add the global test environment
    testing::AddGlobalTestEnvironment(new MoneyTestEnvironment);

    testing::InitGoogleTest(&argc, argv);testing::FLAGS_gtest_death_test_style = "fast";return RUN_ALL_TESTS();

    }
    這樣就擁有了接收和響應(yīng)gtest工程命令行參數(shù)的能力。如果需要在代碼中指定 FLAG,可以使用testing::GTESTFLAG這個(gè)宏來(lái)設(shè)置。比如相對(duì)于命令行參 數(shù)–gtest_output,可以使用testing::GTEST_FLAG(output) = “xml:”;來(lái)設(shè)置。 注意這里不需要加–gtest前綴了,同時(shí),推薦將這句放置InitGoogleTest之前, 這樣就可以使得對(duì)于同樣的參數(shù),命令行參數(shù)優(yōu)先級(jí)高于代碼中指定。
    // MoneyTest.cpp
    int main(int argc, char** argv)
    {
    // Output farmat is XML
    testing::GTEST_FLAG(output) = “xml:”;

    // Add the global test environment testing::AddGlobalTestEnvironment(new MoneyTestEnvironment);testing::InitGoogleTest(&argc, argv);testing::FLAGS_gtest_death_test_style = "fast";return RUN_ALL_TESTS();

    }
    如果需要gtest的設(shè)置系統(tǒng)環(huán)境變量,必須注意的是:

  • 系統(tǒng)環(huán)境變量全大寫(xiě),比如對(duì)于–gtest_output,相應(yīng)的系統(tǒng)環(huán)境變量為 GTEST_OUTPUT
  • 有一個(gè)命令行參數(shù)例外,那就是–gtest_list_tests,它是不接受系統(tǒng)環(huán)境變 量的,只是用 來(lái)羅列測(cè)試案例名稱(chēng)。
    以下是所有命令行參數(shù)列表:
  • 測(cè)試案例集合:
    命令行參數(shù) 說(shuō)明
    –gtest_list_tests 使用這個(gè)參數(shù)時(shí),將不會(huì)執(zhí)行里面的測(cè)試案例,而是輸出一個(gè)案例的列表。
    –gtest_filter 對(duì)執(zhí)行的測(cè)試案例進(jìn)行過(guò)濾,支持通配符 ? 單個(gè)字符 * 任意字符 - 排除,如-a 表示除了a : 取或,如a:b 表示a或b 比如下面的例子: ./foo_test 沒(méi)有指定過(guò)濾條件,運(yùn)行所有案例; ./foo_test –gtest_filter=* 使用通配符*,表示運(yùn)行所有案例; ./foo_test –gtest_filter=FooTest.* 運(yùn)行所有“測(cè)試案例名稱(chēng)(testcase_name)”為FooTest的案例; ./foo_test –gtest_filter=Null:Constructor 運(yùn)行所有“測(cè)試案例名稱(chēng)(testcase_name)”或“測(cè)試名稱(chēng)(test_name)”包含Null或Constructor的案例; ./foo_test –gtest_filter=-DeathTest. 運(yùn)行所有非死亡測(cè)試案例; ./foo_test –gtest_filter=FooTest.*-FooTest.Bar 運(yùn)行所有“測(cè)試案例名稱(chēng)(testcase_name)”為FooTest的案例,但是除了FooTest.Bar這個(gè)案例
    –gtest_also_run_disabled_tests 執(zhí)行案例時(shí),同時(shí)也執(zhí)行被置為無(wú)效的測(cè)試案例。關(guān)于設(shè)置測(cè)試案例無(wú)效的方法為:在測(cè)試案例名稱(chēng)或測(cè)試名稱(chēng)中添加DISABLED前綴。
    –gtest_repeat=[COUNT] 設(shè)置案例重復(fù)運(yùn)行次數(shù): –gtest_repeat=1000:重復(fù)執(zhí)行1000次,即使中途出現(xiàn)錯(cuò)誤; –gtest_repeat=-1: 無(wú)限次數(shù)執(zhí)行 –gtest_repeat=1000 –gtest_break_on_failure:重復(fù)執(zhí)行1000次,并且在第一個(gè)錯(cuò)誤發(fā)生時(shí)立即停止,這個(gè)功能對(duì)調(diào)試非常有用。 –gtest_repeat=1000 –gtest_filter=FooBar:重復(fù)執(zhí)行1000次測(cè)試案例名稱(chēng)為FooBar的案例。
  • 測(cè)試案例輸出
    命令行參數(shù) 說(shuō)明
    –gtest_color(yes/no/auto) 輸出命令行時(shí)是否使用一些五顏六色的顏色,默認(rèn)是 auto。
    –gtest_print_time 輸出命令行時(shí)是否打印每個(gè)測(cè)試案例的執(zhí)行時(shí)間,默認(rèn)是不打印的。
    –gtest_output= xml[:DIRECTORYPATH/:FILEPA\TH] 將測(cè)試結(jié)果輸出到一個(gè)xml中。 –gtest_output=xml: 不指定輸出路徑時(shí),默認(rèn)為案例 當(dāng)前路徑。 –gtest_output=xml:d:\ 指定輸出到某個(gè)目錄 –gtest_output=xml:d:\foo.xml 指定輸出到d:\foo.xml 如果不是指定了特定的文件路徑,gtest每次輸出的報(bào)告不會(huì)覆蓋,而會(huì)以數(shù)字后綴的方式創(chuàng)建
  • 對(duì)案例的異常處理
    命令行參數(shù) 說(shuō)明
    –gtest_break_on_failure 調(diào)試模式下,當(dāng)案例失敗時(shí)停止,方便調(diào)試。
    –gtest_throw_on_failure 當(dāng)案例失敗時(shí)以C++異常的方式拋出。
    –gtest_catch_exceptions 是否捕捉異常。gtest默認(rèn)是不捕捉異常的,因此假如測(cè)試案例拋了一個(gè)異常,很可能會(huì)彈出一個(gè)對(duì)話框,這非常的不友好,同時(shí)也阻礙了測(cè)試案例的運(yùn)行。如果想不彈這個(gè)框,可以通過(guò)設(shè)置這個(gè)參數(shù)來(lái)實(shí)現(xiàn)。如將–gtest_catch_exceptions設(shè)置為一個(gè)非零的數(shù)。 注意:該參數(shù)只在Windows下有效。
    以下是命令行參數(shù)列表在使用過(guò)程中遇到的一些問(wèn)題總結(jié):
  • 同時(shí)使用–gtest_filter和–gtest_output=xml:時(shí),在xml測(cè)試報(bào)告中能否 只包含過(guò)濾后的測(cè)試案例的信息。
  • 有時(shí)在代碼中設(shè)置 testing::GTEST_FLAG(catch_exceptions) = 1和在命 令行中使用–gtest_catch_exceptions結(jié)果稍有不同,在代碼中設(shè)置 FLAG方式有時(shí)候捕捉不了某些異常,但是通過(guò)命令行參數(shù)的方式一般都不會(huì) 有問(wèn)題。最后處理辦法是既在代碼中設(shè)置FLAG,又在命令行參數(shù)中傳 入–gtest_catch_exceptions,估計(jì)是gtest在catch_exceptions方面不 夠穩(wěn)定的原因?qū)е隆?br /> 到目前為止,我們已經(jīng)掌握了Gtest常用的測(cè)試方法。Money例子的整體的 測(cè)試代碼參考如下:
    // file: MoneyTest.cpp
  • #include
    #include
    #include <gtest\gtest.h>
    #include “Money.h”

    // EXPECT Testing
    TEST(MoneyConstructorTest, TestConstructor)
    {
    // Set up
    const std::string currencyAA(“AA”);
    const double longNumber = 123.456;

    // Process Money money(longNumber, currencyAA);// Check EXPECT_EQ(longNumber, money.getAmount()); EXPECT_STREQ("AA", money.getCurrency().c_str());//EXPECT_EQ(555, money.getAmount());std::cout << "Code after EXPECT!" << std::endl;

    }
    // End EXPECT Testing

    // ASSERT Testing
    TEST(MoneyConstructorTest, TestConstructorAssert)
    {
    // Set up
    const std::string currencyBB(“ASSERT”);
    const double longNumber = 222.222;

    // Process Money money(longNumber, currencyBB);// Check ASSERT_STREQ("AA", money.getCurrency().c_str());std::cout << "Code after ASSERT!" << std::endl;

    }
    // End ASSERT Testing

    // Throw Testing
    TEST(MoneyThrowTest, ThrowTest)
    {
    // Set up
    const Money money123AA(123, “AA”);

    // Process Money money123BB(123, "BB");EXPECT_ANY_THROW(money123BB += money123AA);EXPECT_THROW(money123BB += money123AA, IncompatibleMoneyError);

    }
    // End Throw Testing

    // Global Event Testing
    class MoneyTestEnvironment : public testing::Environment
    {
    public:
    virtual void SetUp()
    {
    std::cout << “Money Global Event SetUp.” << std::endl;
    }

    virtual void TearDown() {std::cout << "Money Global Event TearDown" << std::endl; }

    };
    // End Global Event Testing

    // Suite Event Testing
    class MoneySuiteEventTest : public testing::Test
    {
    public:
    static void SetUpTestCase()
    {
    std::cout << “Money Test SuiteEventTest SetUpTestCase.” << std::endl;
    }

    static void TearDownTestCase() {std::cout << "Money Test SuiteEventTest TearDownTestCase." << std::endl; }

    };

    TEST_F(MoneySuiteEventTest, SuiteTestCaseOne)
    {
    const std::string currencyCC(“CC”);
    const double longNumber = 123.456;

    // Process Money money(longNumber, currencyCC);// Check EXPECT_EQ(longNumber, money.getAmount()); EXPECT_STREQ("CC", money.getCurrency().c_str());

    }

    TEST_F(MoneySuiteEventTest, SuiteTestCaseTwo)
    {
    const std::string currencyCC(“DD”);
    const double longNumber = 123.456;

    // Process Money money(longNumber, currencyCC);// Check EXPECT_EQ(longNumber, money.getAmount()); EXPECT_STREQ("DD", money.getCurrency().c_str());

    }
    // End Suite Event Testing

    // TestCase Event Testing
    class MoneyTestCaseTest : public testing::Test
    {
    public:
    void SetUp()
    {
    std::cout << “Money Test MoneyTestCaseTest SetUp.” << std::endl;
    }

    void TearDown() {std::cout << "Money Test MoneyTestCaseTest TearDown." << std::endl; }

    };

    TEST_F(MoneyTestCaseTest, TestCaseTestOne)
    {
    const std::string currencyDD(“TestCaseTestOne”);
    const double longNumber = 123.456;

    // Process Money money(longNumber, currencyDD);// Check EXPECT_EQ(longNumber, money.getAmount());

    }

    TEST_F(MoneyTestCaseTest, TestCaseTestTwo)
    {
    const std::string currencyDD(“TestCaseTestTwo”);
    const double longNumber = 123.456;

    // Process Money money(longNumber, currencyDD);// Check EXPECT_EQ(longNumber, money.getAmount());

    }
    // End TestCase Event Testing

    // Parameter Testing one
    class MoneyParameterTest : public testing::TestWithParam
    {
    public:
    };

    TEST_P(MoneyParameterTest, ParameterTest)
    {
    double acount = GetParam();
    Money money(acount, “Test”);
    EXPECT_EQ(acount, money.getAmount());
    }

    INSTANTIATE_TEST_CASE_P(ParameterTest, MoneyParameterTest,
    testing::Values(111.111, 222.2222, 333.3333, 444.44444));
    // End Parameter Testing one

    // Parameter Extual Testing two
    // Step one
    template
    class MoneyTemplateTest : public testing::Test
    {
    public:
    typedef std::list List;
    static T shared;
    T value;
    };

    // Step two
    typedef testing::Types<double, long double> MoneyTypes;
    TYPED_TEST_CASE(MoneyTemplateTest, MoneyTypes);

    // Step three
    TYPED_TEST(MoneyTemplateTest, TemplateTest)
    {
    // Inside a test, refer to the special name TypeParam to get the type
    // parameter. Since we are inside a derived class template, C++ requires
    // us to visit the members of MoneyTemplateTest via ‘this’.
    TypeParam n = this->value;

    // To refer to typedefs in the fixture, add the 'typename TestFixture::' // prefix. The 'typename' is required to satisfy the compiler. typename TestFixture::List values; values.push_back(n);

    }
    // End Parameter Extual Testing two

    // Death Test
    TEST(MoneyDeathTest, DeathTest)
    {
    // Set up
    Money moneyAA(123.456, “DeathTestOne”);
    Money moneyBB(0.123456, “DeathTestTwo”);

    // Process EXPECT_DEATH(moneyAA+=moneyBB ,"Test MoneyDeathTest");

    }
    // End Death Test

    int main(int argc, char** argv)
    {
    testing::GTEST_FLAG(output) = “xml:”;

    // Add the global test environment testing::AddGlobalTestEnvironment(new MoneyTestEnvironment);testing::InitGoogleTest(&argc, argv);testing::FLAGS_gtest_death_test_style = "fast";return RUN_ALL_TESTS();

    }

    4 作業(yè)
    4.1 編寫(xiě)一個(gè)DemoContainer類(lèi),按以下接口要求實(shí)現(xiàn):

  • int get_size(void)
    get_size函數(shù)的功能是得到這個(gè)"容器"的大小,也就是這個(gè)"容器"里所有元 素的數(shù)量,如果這個(gè)"容器"里沒(méi)有任何元素,那么返回0。
  • int add_item(const string& str)
    add_item 的作用是向"容器"中添加一個(gè)字符串元素。如果"容器"中已經(jīng)存在 內(nèi)容相同的元素,則添加失敗返回-1。如果添加成功,返回這個(gè)元素在"容器 "中對(duì)應(yīng)的索引值。
  • string get_item(int index)
    get_item的作用是取得"容器"中索引為"index"的元素。如果參數(shù)"index"大 于(包括等于)當(dāng)前"容器"中所有元素的數(shù)量,或者參數(shù)"index"是非正整數(shù), 以上情況都拋出異常"out_of_range"。
  • bool remove_item(int index)
    remove_item的作用是移除"容器"中索引為"index"的元素。如果參數(shù) "index"大于(包括等于)當(dāng)前"容器"大小,或者參數(shù)"index"是非正整數(shù),返回 “false”;否則刪除"容器"中對(duì)應(yīng)索引為"index"的元素,并返回true。
    大家根據(jù)提供的功能接口為接口來(lái)添加測(cè)試用例,再根據(jù)測(cè)試用例來(lái)完成功能的 代碼。 ·
    5 參考文獻(xiàn)
    http://www.cnblogs.com/coderzh/archive/2009/04/06/1426755.html
    https://code.google.com/p/googletest/w/list
    http://developer.51cto.com/art/201108/285290.htm
    http://www.doc88.com/p-079433664365.html
    Author: 于麗香 yu-lx@neusoft.com
    Date: 2018-09-01 10:28:59 CST
    HTML generated by org-mode 6.33x in emacs 23
  • 總結(jié)

    以上是生活随笔為你收集整理的Gtest 测试指导 入门基础(A)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

    日本性生活免费看 | 国产精品网站 | 区一区二在线 | 2021久久| 亚洲女欲精品久久久久久久18 | 欧美精品亚洲精品 | 亚洲精品久久久久中文字幕二区 | 国产精品男女视频 | 日韩欧美在线第一页 | 亚洲天堂网站视频 | 成人在线免费观看视视频 | jizzjizzjizz亚洲 | 日韩欧美一区二区三区免费观看 | 狠狠干天天操 | 麻豆国产电影 | 激情久久伊人 | 国产亚洲精品久久久久动 | 中文亚洲欧美日韩 | 精品在线亚洲视频 | 毛片网在线观看 | 中文在线字幕免费观看 | 91九色精品 | 91精品国产综合久久婷婷香蕉 | 在线看v片成人 | 久久精品79国产精品 | 97超级碰碰 | www免费视频com━ | 中文字幕韩在线第一页 | 欧美成人性战久久 | www.黄色片.com | 美女性爽视频国产免费app | 麻豆影视在线免费观看 | 黄污视频网站 | a'aaa级片在线观看 | 99视频99 | 亚洲va欧美va国产va黑人 | 天天天操天天天干 | 色网址99| 一区 二区 精品 | 黄色高清视频在线观看 | 欧美作爱视频 | 特黄特色特刺激视频免费播放 | 在线电影 你懂得 | 国产精品网红直播 | av888.com| 91传媒在线观看 | 天天干天天干天天干天天干天天干天天干 | 91精品视频免费在线观看 | 亚洲视频免费在线看 | 国产视频亚洲精品 | 中文字幕在线观看91 | 黄色毛片视频免费观看中文 | 最新中文字幕在线资源 | 亚洲精品网址在线观看 | av黄色亚洲| 91九色蝌蚪| 亚洲视频资源在线 | 二区三区精品 | 成人黄色中文字幕 | 日韩高清 一区 | 国产日韩三级 | 99免费看片| 激情综合亚洲精品 | 亚洲成人蜜桃 | 操久久网| 2023av在线| 久草在线一免费新视频 | 黄色视屏免费在线观看 | 在线免费视频a | 久久不射网站 | 国产破处在线视频 | 欧美精品在线观看一区 | 欧美一区二区在线 | 色伊人网 | 国产一区视频导航 | 国产98色在线 | 日韩 | 亚洲成av| 手机av电影在线观看 | 色综合婷婷 | 日韩欧美在线观看一区二区 | 中文字幕在线日 | 久久乐九色婷婷综合色狠狠182 | 久久综合99| 国产精品久久久久久模特 | 91av原创| 久久影院午夜论 | 97国产小视频 | 视频三区 | 在线观看精品视频 | 日韩美av在线 | av在线日韩 | 亚洲天堂毛片 | 91人人爽人人爽人人精88v | 中文字幕免费观看全部电影 | 免费在线看成人av | 亚洲尺码电影av久久 | 狠狠干 狠狠操 | 日韩高清av | 国产一区免费 | 中文字幕一区二区三区四区视频 | 国产九九九九九 | 亚洲特级毛片 | 91亚洲综合 | 国产99久久久欧美黑人 | 中文字幕av全部资源www中文字幕在线观看 | 久久久久久久18 | 亚洲一级国产 | 国产精品成人一区 | 97理论电影| 超碰com| 日韩一级电影在线观看 | 亚洲综合视频在线观看 | 国产精品日韩久久久久 | 久久99精品国产91久久来源 | 久久在线观看视频 | 国产午夜精品一区二区三区在线观看 | 成人av久久| 欧美一级片在线 | 久久久精品| 久久视频在线视频 | 美女视频黄免费的久久 | 亚洲国产三级在线 | 亚洲视频电影在线 | 欧美激情视频一区二区三区免费 | 99久久精品久久久久久清纯 | 色是在线视频 | 91人人爽人人爽人人精88v | 久久精品xxx| 国产91精品高清一区二区三区 | 在线综合 亚洲 欧美在线视频 | av在线精品 | 久久永久视频 | 国产精品久久99综合免费观看尤物 | 中文字幕一区二区三区四区在线视频 | 日本黄区免费视频观看 | 日女人免费视频 | 韩国一区视频 | 91精品久久久久久久99蜜桃 | 97超碰资源总站 | 天天爱天天色 | 久久在线视频精品 | 国产福利一区在线观看 | 亚洲欧美激情插 | 韩国三级在线一区 | 欧美视频在线观看免费网址 | 国产va饥渴难耐女保洁员在线观看 | 视频1区2区| 亚洲性xxxx | 狠狠色狠狠色综合日日小说 | 精品福利视频在线观看 | 久久香蕉国产精品麻豆粉嫩av | 国产精品3 | 成人小视频在线观看免费 | 国产黄色av网站 | 日韩免费视频一区二区 | 最新av在线免费观看 | 国产成人精品一区一区一区 | 国产福利91精品一区二区三区 | 久久不卡免费视频 | www成人av| 少妇性bbb搡bbb爽爽爽欧美 | 在线观看小视频 | 色综合激情网 | 久久九九精品久久 | 99综合电影在线视频 | 中文字幕在线免费看 | 久久伊99综合婷婷久久伊 | 久久一区二区免费视频 | 岛国av在线免费 | 久久精品中文字幕一区二区三区 | 人人干人人超 | 久久久国产日韩 | 日韩两性视频 | 国内精品久久久久国产 | 亚洲va欧美 | 国产国产人免费人成免费视频 | 在线观看视频国产一区 | 日韩欧美高清一区二区三区 | 96精品视频 | 超级碰视频 | 中文字幕精品一区 | 日日夜夜天天操 | 日韩中文在线观看 | 久久免费精品国产 | 久久er99热精品一区二区 | 蜜臀av性久久久久蜜臀aⅴ流畅 | 波多野结衣在线视频免费观看 | 欧美精品乱码久久久久久按摩 | 亚洲精品乱码 | 中文字幕在线观看网站 | 国产91aaa | 中文字幕欧美日韩va免费视频 | 免费在线观看成人av | 久久超碰97 | 国产理伦在线 | 亚洲精品在线国产 | 精品视频专区 | 日韩一级理论片 | 伊人色综合久久天天网 | 日韩国产精品久久久久久亚洲 | 国产成人在线免费观看 | 国产亚洲视频系列 | 综合天堂av久久久久久久 | 日韩av视屏在线观看 | 久亚洲精品 | 99综合影院在线 | 色wwwww| 91成品人影院 | 国产精品自产拍在线观看蜜 | 久久99精品久久久久久 | 免费日韩一区二区三区 | 久久久96| 一区二区三区韩国免费中文网站 | 国产高清永久免费 | 久久免费看a级毛毛片 | 探花视频免费观看高清视频 | 国产日韩视频在线播放 | 日韩欧美在线播放 | 在线午夜电影神马影院 | 国产剧情在线一区 | 免费在线观看成人av | 激情丁香婷婷 | 亚洲日日日 | 欧美日韩国语 | 亚洲欧洲精品一区二区精品久久久 | 免费av大片 | 国产成人精品久久久久 | 精品久久久久久久久久久久久久久久 | 精品免费视频. | 欧美一区二区三区在线播放 | 亚洲国产精品日韩 | 久久视频在线免费观看 | 精品国产一区二区三区久久久蜜月 | 免费视频二区 | 国产午夜剧场 | 天天舔天天射天天操 | 黄色成人av在线 | 日韩精品三区四区 | 亚洲第一av在线播放 | 免费三级网 | 中文字幕一区二区三区四区在线视频 | 免费黄色av电影 | 亚洲高清在线视频 | 一区二区三区日韩在线 | 国产伦精品一区二区三区四区视频 | 碰超在线| 四虎永久免费在线观看 | 18+视频网站链接 | 国产精品久久久久久久久久直播 | 色综合久久天天 | 视频福利在线观看 | 91精品天码美女少妇 | 超碰免费在线公开 | 久久久久久久久久久久久久av | 99免费在线 | 国产 成人 久久 | 麻花天美星空视频 | 伊人狠狠色 | 亚洲精品一区二区久 | 欧美日韩国产精品一区二区三区 | 日韩专区 在线 | 黄色aaa级片 | 韩国一区二区在线观看 | 免费在线观看午夜视频 | 天天射天天射 | 国产精品视频永久免费播放 | 麻豆一区二区三区视频 | 超碰97免费| 久久激情综合网 | 国产精品久久久久9999吃药 | 国产精品欧美激情在线观看 | 亚洲欧美日韩在线一区二区 | 亚洲va欧美va国产va黑人 | www.天天操.com | 色久天| 欧美人zozo| 久久精品一区二 | 日韩精品字幕 | 中文字幕在线看 | 高清av免费观看 | 日韩手机视频 | 天天摸天天弄 | 亚洲精区二区三区四区麻豆 | 亚洲精品午夜久久久久久久久久久 | 日韩在线观看小视频 | 一级精品视频在线观看宜春院 | 99视频播放| 国产亚洲视频系列 | 国产网红在线观看 | 毛片基地黄久久久久久天堂 | 日韩色中色| 欧美成人黄色片 | 亚洲精品视频在 | 免费成人黄色av | 91av免费看 | 91少妇精拍在线播放 | 国产在线a | 国产伦理久久精品久久久久_ | 免费观看福利视频 | 久久 亚洲视频 | 免费在线一区二区 | av一级网站 | 国产麻豆精品久久一二三 | 女人18毛片a级毛片一区二区 | 欧美福利久久 | 久久精品精品电影网 | 精品美女在线观看 | 久久大视频 | 精品在线播放视频 | 久久综合婷婷国产二区高清 | 久久精品中文字幕免费mv | 丁香婷婷久久 | 激情久久一区二区三区 | 日韩网站一区 | 日韩电影精品 | 青草视频在线免费 | 久草在线费播放视频 | 国产午夜不卡 | 国产手机免费视频 | 亚洲精品小区久久久久久 | 亚洲精品xxxx | 精品国产电影一区 | 日韩色一区二区三区 | 国产精品毛片一区视频播 | 中文字幕一区二区三区乱码在线 | 久久激情五月丁香伊人 | 日本中文字幕在线视频 | 国产成人av在线影院 | 欧美性天天 | av丝袜制服 | 人人爱天天操 | 超碰97.com| 日韩av中文| 国产精品毛片一区二区在线 | 干干干操操操 | 激情五月亚洲 | 国产高清视频免费 | 欧美日韩视频免费 | 在线免费视频a | 国产91精品高清一区二区三区 | 久久少妇 | 操综合 | 国内综合精品午夜久久资源 | 国产午夜精品一区二区三区在线观看 | 狠狠狠色丁香综合久久天下网 | 成av人电影 | av成人免费在线观看 | 99av在线视频 | av中文字幕日韩 | 91完整版在线观看 | 亚洲精品自在在线观看 | 五月开心婷婷 | www.eeuss影院av撸 | 免费日p视频 | 中文字幕日本特黄aa毛片 | 99精品免费在线观看 | 亚洲国产黄色片 | 一级黄色片在线免费观看 | 国产精品一区欧美 | 在线亚洲成人 | 久久国产露脸精品国产 | 91一区啪爱嗯打偷拍欧美 | 久久久久久久国产精品视频 | 国产福利不卡视频 | 中文字幕在线播放一区 | 午夜av在线电影 | 黄色网www| 九九九九九精品 | 亚洲黄色区 | 天天做天天爱天天综合网 | 天天干天天在线 | 国产成人性色生活片 | 手机av电影在线观看 | 四虎在线永久免费观看 | 欧美成人在线网站 | 色婷婷亚洲婷婷 | 国产一级片直播 | 久久久久欠精品国产毛片国产毛生 | 日韩视频在线播放 | 久久久久久久久网站 | 国产a精品 | 精品福利在线 | 国产激情免费 | 久久久久激情视频 | 欧美欧美| 欧美孕妇视频 | 国产高清不卡 | 亚洲一区二区观看 | 国产成人av一区二区三区在线观看 | 国产精品美女久久久久久2018 | 在线免费黄色av | 五月天激情综合网 | 欧美一级性 | 中文字幕一区二区三区久久 | 亚洲欧洲国产精品 | 四虎永久视频 | 国产一级久久久 | 国产视频在线观看免费 | 超碰在线观看av.com | 国产精品乱码在线 | 一区二区三区在线免费观看视频 | 国产123区在线观看 国产精品麻豆91 | 精品99在线观看 | 蜜臀久久99精品久久久久久网站 | www.com操| 亚洲视频高清 | 久久精品免费观看 | 亚洲另类视频在线观看 | 亚洲久在线| 青青河边草免费 | 午夜精品久久久久久久久久久久久久 | 波多野结衣在线观看一区二区三区 | 精品视频中文字幕 | 亚州精品国产 | 91成人免费看 | 国产免费黄视频在线观看 | 二区三区在线视频 | 日韩欧美精品一区二区三区经典 | 免费网站色 | 亚洲成人黄色网址 | 五月天久久激情 | 中文在线亚洲 | www免费黄色| www.99热精品| 久久久久久精 | 亚洲国产大片 | 成年人在线电影 | 久久午夜色播影院免费高清 | 中文字幕免费观看全部电影 | 久草在线视频国产 | www.久久久 | av免费线看 | 久久久久国产一区二区三区 | 色婷婷在线播放 | 国产精品嫩草影院9 | 最新日韩视频 | 国产专区日韩专区 | 亚洲男男gaygayxxxgv | 97在线资源 | 在线高清av | 日韩在线不卡视频 | 国产女教师精品久久av | 日韩av中文字幕在线 | 久久综合亚洲鲁鲁五月久久 | 波多野结衣在线视频免费观看 | 久久国内精品99久久6app | 国产精品18久久久久vr手机版特色 | 五月婷丁香网 | 精品美女久久久久 | av一区在线 | 麻豆果冻剧传媒在线播放 | 国产v在线播放 | 五月天激情综合网 | 亚洲欧美视频网站 | 欧美 日韩 国产 成人 在线 | 久久久免费精品国产一区二区 | 国产精品永久久久久久久www | 成人香蕉视频 | 亚洲自拍偷拍色图 | 97在线看 | 天天爽夜夜爽精品视频婷婷 | 欧美日韩免费视频 | 天天草视频 | 在线视频观看亚洲 | 天天天天射| 亚洲精品免费在线 | 国产成人资源 | 国内99视频 | 久久国产精品偷 | 成年人视频在线免费 | 午夜精品久久久久久中宇69 | 久久在线影院 | 国产免费一区二区三区最新 | 日韩精品一区二区三区高清免费 | 国产精品免费视频久久久 | 久久美女精品 | 最近最新最好看中文视频 | 97av在线视频 | 亚洲国产字幕 | 久热av| 四月婷婷在线观看 | 欧美一区二区免费在线观看 | 国产1区2区3区精品美女 | 亚洲少妇天堂 | 99视频偷窥在线精品国自产拍 | 国内精品亚洲 | 成人免费网视频 | 国产综合小视频 | 91av在线免费视频 | 中文字幕中文字幕中文字幕 | 天天爱天天色 | 97av影院| 亚洲精品乱码久久久久久蜜桃不爽 | 91在线日本 | 五月婷婷综 | 在线国产精品一区 | 五月天天av | 欧美精品少妇xxxxx喷水 | 91av电影网 | 国产群p视频 | 一区二区三区免费在线 | 欧美激情另类文学 | 欧美激情第28页 | 久久精品久久久精品美女 | 三级性生活视频 | 嫩小bbbb摸bbb摸bbb| 色小说在线| 国内精品久久久久影院男同志 | 在线电影日韩 | 人人爽久久涩噜噜噜网站 | 久久成人黄色 | 成人久久18免费网站 | 国产美女永久免费 | 99精品在线视频观看 | 天天操天天爽天天干 | 激情久久一区二区三区 | 久久9999久久 | 欧美成人91 | 日日干夜夜干 | 国产精品久久久久久久久久久免费 | 久久不卡日韩美女 | 91av视频在线观看 | 成人免费xxxxxx视频 | 久久无码精品一区二区三区 | 麻豆91在线播放 | 欧美在线18| 福利一区二区三区四区 | 亚洲一区久久久 | 在线视频国产区 | 麻花豆传媒mv在线观看 | 国产免费高清 | 国产又粗又猛又黄视频 | 国产精品专区在线观看 | 国产精品 中文在线 | 91九色视频在线 | 黄a在线看 | 天天操天天色天天射 | 欧美激情综合五月色丁香小说 | 夜夜躁日日躁狠狠躁 | 国产毛片久久久 | 国产96精品 | 伊人永久 | 国产理论免费 | 日日操操| 日本h视频在线观看 | 久久国产经典 | 精品一区二区三区久久久 | 人人干狠狠操 | 国产在线观看地址 | 亚洲粉嫩av | 91麻豆免费版| 激情综合久久 | 在线观看国产中文字幕 | 亚洲精品欧洲精品 | 成人亚洲欧美 | 日韩av午夜在线观看 | 黄色一二级片 | 91xav| 日韩中文字幕免费视频 | 色综合久久综合 | 精品久久久成人 | 韩国av免费 | 97av色 | 欧美日视频 | 精品视频免费播放 | 久久在线视频在线 | 超碰人人91 | 91视频在线看| 免费国产一区二区视频 | www.天天综合 | 国产亚洲精品久久久久动 | 欧美一级片在线观看视频 | av色综合网 | 欧美日韩在线观看一区二区三区 | 91爱爱免费观看 | 久久久久久国产一区二区三区 | 久久久久久久久久久久久国产精品 | 久久免费视频一区 | 国产精品色 | 久久久久久免费毛片精品 | 九九色视频 | 欧美日韩不卡在线视频 | 国产免费嫩草影院 | 色视频网站在线观看一=区 a视频免费在线观看 | 久久久久久久看片 | 高清久久久| 日本激情视频中文字幕 | 久久中文网 | 狠狠搞,com| 91看片看淫黄大片 | 欧美日韩国产高清视频 | 国内精品久久久久影院一蜜桃 | 久久久www成人免费精品张筱雨 | 免费在线色视频 | 在线看v片成人 | 精品国产乱码久久久久久浪潮 | 免费看成年人 | 国产专区在线播放 | 99久热在线精品视频 | 亚洲黄色免费网站 | 中文字幕视频免费观看 | 久久国产精品精品国产色婷婷 | 黄色成年 | 欧美一区二区免费在线观看 | 久久伦理电影网 | 国产精彩视频一区 | 麻豆91精品91久久久 | 国产精品国产三级国产 | 97电影院在线观看 | 色综合久久久久久中文网 | 九九九九热精品免费视频点播观看 | 亚洲天天干 | 成人久久久久久久久 | 6080yy精品一区二区三区 | 麻豆网站免费观看 | 91久久丝袜国产露脸动漫 | 九九精品视频在线看 | 人人爽人人做 | 一二三四精品 | 在线免费观看视频一区 | 久久久 精品 | 国产黄色精品在线 | 欧美乱码精品一区二区 | 日本久久综合视频 | 亚洲国产电影在线观看 | 免费看的毛片 | 99久久这里只有精品 | 黄色免费高清视频 | 精品国产视频一区 | 亚洲天堂网在线视频观看 | 人人射av| 日本 在线 视频 中文 有码 | 日韩特级毛片 | 91精品蜜桃 | 日韩欧美69 | 欧洲一区二区在线观看 | japanese黑人亚洲人4k | 久久久久久麻豆 | 天天草天天色 | 亚洲最大av | 久久国产精品影视 | 日韩精品电影在线播放 | 97视频在线观看成人 | 日韩午夜剧场 | 在线国产一区二区 | 久久久久免费网站 | 久久久久免费看 | 亚州五月| 免费色视频网址 | 五月激情亚洲 | 狠狠操综合 | 日韩欧美在线视频一区二区三区 | 亚洲高清视频在线观看 | 免费观看完整版无人区 | 国产99久久久国产 | 日韩欧美一区二区三区黑寡妇 | a v在线观看 | 又黄又爽又湿又无遮挡的在线视频 | 亚洲精品成人av在线 | 高清日韩一区二区 | 天天操欧美 | 亚洲日本va中文字幕 | 天天av天天 | 成人在线免费视频观看 | 婷婷在线免费 | 亚洲va在线va天堂 | 视频在线在亚洲 | 婷婷五月色综合 | 国产v在线 | 久久桃花网| 成人一区二区三区在线 | 毛片永久免费 | 亚洲一级二级三级 | 中文一区在线观看 | 欧美在线1 | 国产aaa毛片 | 视色网站| 久久国产成人午夜av影院宅 | 久久久久久久久久久福利 | 日韩精品视频第一页 | 日韩成人精品一区二区 | 色老板在线视频 | 人人干免费 | 黄色软件在线看 | 手机在线永久免费观看av片 | 亚洲黄在线观看 | 美女视频黄是免费的 | 国产vs久久 | 黄网站色欧美视频 | 亚洲精品午夜久久久 | 久久国产免费看 | 国产精品成人免费一区久久羞羞 | 欧美国产大片 | 国产婷婷vvvv激情久 | 精品极品在线 | 婷婷午夜天 | 国产成本人视频在线观看 | 国产精品激情在线观看 | 最近中文字幕视频完整版 | av在线免费在线 | 午夜精品久久久久久久99水蜜桃 | 精品色999 | a在线一区 | 久久涩涩网站 | 在线观看精品黄av片免费 | 精品亚洲免a | 一区二区视频在线免费观看 | 麻豆网站免费观看 | 国产香蕉久久 | 久草91视频 | 色福利网站 | 亚洲视频axxx| 日日干日日操 | 婷婷久久网站 | 激情av五月婷婷 | 人人爽夜夜爽 | 在线免费成人 | 久久国产一区二区 | 天天操夜夜干 | 波多野结衣电影一区二区 | 久久精品久久久久久久 | 国产精品伦一区二区三区视频 | 黄色av成人在线 | 中文字幕在线播放av | 日韩电影在线一区二区 | 天天操夜夜操夜夜操 | 国产一级片久久 | 久草在线观看视频免费 | 亚洲在线成人精品 | 亚洲首页 | 狠狠色狠狠色合久久伊人 | 不卡视频在线 | 天天做天天射 | 狠狠干美女 | 久久久久国产一区二区 | 二区精品视频 | 天天色天天操天天爽 | 国产精在线 | 国产高清一| 亚洲理论电影 | 手机看片 | 国产香蕉视频在线观看 | 免费在线观看av电影 | 久久精彩视频 | 国产在线无 | 99亚洲天堂| 黄污网站在线观看 | 69国产精品成人在线播放 | 亚洲毛片一区二区三区 | av观看久久久 | 国产精品久久嫩一区二区免费 | 日韩精品视频久久 | 成年人免费在线观看网站 | 激情久久综合网 | 97网在线观看 | 日韩一区二区在线免费观看 | 麻豆91网站 | 久久久久国产a免费观看rela | 丁香婷婷激情网 | 成人一区二区在线 | 久久香蕉电影网 | 麻豆视频免费版 | 国产最新在线观看 | 91视频网址入口 | 美女视频网站久久 | 在线观看91久久久久久 | 欧美日韩在线视频一区二区 | 亚洲精品永久免费视频 | 国产剧情一区二区 | 91秒拍国产福利一区 | 制服丝袜欧美 | 欧美在一区 | 成人a毛片 | 91免费视频网站在线观看 | 国产精品mv| 国产精品毛片一区二区在线 | 永久免费av在线播放 | 日韩在线中文字幕 | 国产一区高清在线观看 | 国产一级不卡视频 | 色婷婷婷 | 99精品视频在线播放观看 | 国内精品小视频 | 午夜久久福利视频 | 美女国产在线 | 精品视频一区在线观看 | 91在线免费视频 | 亚洲 欧美 国产 va在线影院 | 久久综合五月 | 女人18毛片a级毛片一区二区 | 久草国产在线 | 欧美一级免费片 | 久久不卡日韩美女 | 久久成人国产精品免费软件 | 在线视频观看你懂的 | 色婷婷国产精品 | 精品国产一区二区三区噜噜噜 | 国产成人一区二区三区电影 | 久久麻豆精品 | 最近中文字幕大全 | 久久久视频在线 | 福利视频导航网址 | 在线观看日韩精品视频 | 97热在线观看 | 国产成人99av超碰超爽 | 欧美日韩中文字幕视频 | 亚洲无吗av | 伊人小视频 | 在线观看黄网站 | 九色视频网址 | 成人精品视频久久久久 | 中文字幕在线影视资源 | av免费在线看网站 | 黄色资源网站 | 国产精品乱码在线 | 天天看天天干 | 成人免费视频视频在线观看 免费 | 日本黄色免费播放 | 久久久久久久亚洲精品 | 91禁在线观看 | 久久成人久久 | 国产在线小视频 | 在线观看精品一区 | 人人射人人插 | 免费精品 | 亚洲精品久久久久久久不卡四虎 | 成人动漫一区二区 | 国产精品99久久久久久武松影视 | 日韩精品一区二区在线 | 亚洲国产成人精品在线 | 婷婷丁香久久五月婷婷 | 亚洲精品福利在线观看 | 日韩精品1区2区 | 91av小视频| 久久久高清一区二区三区 | 久久99国产精品久久 | 91视频在线自拍 | 久草com | 五月婷婷色综合 | 午夜精品三区 | 五月婷婷综合网 | 久久丁香 | 日韩中文在线观看 | 亚洲一级片在线看 | 亚洲精品视频在线观看免费视频 | 狠狠色丁香婷婷综合橹88 | 国产免费不卡 | 97成人资源站 | 99精品在线视频播放 | 国产中文视频 | 天天草综合 | 国产91精品一区二区 | 婷婷狠狠操 | 免费看片亚洲 | 亚洲妇女av | 成人cosplay福利网站 | 欧美精品一区二区在线观看 | 91亚洲精品国偷拍 | 国产尤物一区二区三区 | 久久高清av | 操夜夜操 | 日韩午夜一级片 | 亚洲女同videos | 99日精品 | 国产精品久久久久久久久久久久午 | 久久精品第一页 | 91丨九色丨高潮丰满 | 久久久久久久久影院 | 日韩肉感妇bbwbbwbbw | 丁香色婷婷 | 国产精品亚州 | 九月婷婷色 | 1024久久 | www.成人久久 | 人人插人人艹 | 久久精品免费看 | 色婷婷五 | 久久国产免 | 中文字幕永久在线 | www久久com | 国产男女无遮挡猛进猛出在线观看 | 青青射 | 成人免费中文字幕 | 午夜在线国产 | 日韩一区精品 | 香蕉视频18 | 午夜精品福利一区二区三区蜜桃 | 黄a网 | 久久草 | a级国产乱理伦片在线观看 亚洲3级 | 91成人网在线 | 久久久久成人精品亚洲国产 | 美女黄频免费 | 亚洲精品国产综合久久 | 久久精品视频免费 | 国产精品欧美精品 | 国产在线视频一区 | 亚洲成av人影院 | 超碰人人舔| 久久精品老司机 | 人人狠狠综合久久亚洲婷 | 精品久久精品久久 | 国产精品久久久久久久久毛片 | 日日草视频 | 一区二区三区精品在线 | 午夜电影久久 | 国产中文字幕免费 | 日韩欧美69 | 夜夜嗨av色一区二区不卡 | 欧美日韩在线观看视频 | 国产精品观看 | 久久久久亚洲精品国产 | 又大又硬又黄又爽视频在线观看 | 国产97av | 免费观看av| 97在线精品国自产拍中文 | 亚洲天堂社区 | 成年人app网址 | 久久影视中文字幕 | 欧美va日韩va | 主播av在线 | 成人黄色视 | 欧美日韩一区二区三区在线免费观看 | 97涩涩视频 | 欧美色噜噜噜 | 国产精品久久久区三区天天噜 | 日韩久久精品一区二区 | 国产精品9999久久久久仙踪林 | 国产视频久久久 | 国产精品精品久久久 | 亚洲h视频在线 | 丁香久久久 | 日本精品在线视频 | 在线视频 91 | 国产伦精品一区二区三区… | 国产高清视频在线播放 | 欧美日韩裸体免费视频 | 日本激情视频中文字幕 | 成人小视频在线免费观看 | 欧洲精品视频一区二区 | 国产成人av免费在线观看 | 久草视频免费 | 精品1区2区3区 | 中文国产字幕在线观看 | 天天色天天色 | 91丨精品丨蝌蚪丨白丝jk | 日韩三级在线 | 久久综合九色欧美综合狠狠 | 99精品在线视频观看 | 久久精品视频4 | 中文字幕九九 | 国产精品女同一区二区三区久久夜 | 在线免费观看黄色大片 | 91av在线免费观看 | 97视频免费在线 | 国产综合91 | 日本性生活免费看 | 五月天色综合 | 日韩中文字幕免费在线播放 | 婷婷六月久久 | 天天综合网 天天 | 69国产成人综合久久精品欧美 | 欧美国产日韩久久 | 亚洲成aⅴ人片久久青草影院 | 香蕉免费| 中国一级片在线观看 | 日韩高清av在线 | av三级在线看 | 97在线观看免费观看高清 | 亚洲午夜精品久久久久久久久久久久 | 久久国产99| av亚洲产国偷v产偷v自拍小说 | 干av在线 | 一级大片在线观看 | 视频91 | 日韩午夜大片 | 一区二区三区在线看 | 91试看 | 黄a网站 | 激情欧美丁香 | 一级大片在线观看 | 日日日网 | 手机av在线不卡 | 97国产视频 | 在线视频1卡二卡三卡 | 欧美日韩视频在线一区 | 久久精品一区二区三区中文字幕 | 国产免费成人av | 久久精品看| 国产精品免费视频观看 | 亚洲国产一区二区精品专区 | 91伊人影院| 日韩xxx视频 | 久久综合五月天婷婷伊人 | 麻豆视频在线免费 | 午夜精品电影 | 福利久久久| 欧美一级视频在线观看 |