Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 281|回复: 0

[默认分类] 玩转Google开源C++单元测试框架Google Test系列(gtest)之二 - 断言

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-7-11 15:45:32 | 显示全部楼层 |阅读模式
    一、前言
    这篇文章主要总结gtest中的所有断言相关的宏。 gtest中,断言的宏可以理解为分为两类,一类是ASSERT系列,一类是EXPECT系列。一个直观的解释就是:

    1. ASSERT_* 系列的断言,当检查点失败时,退出当前函数(注意:并非退出当前案例)。

    2. EXPECT_* 系列的断言,当检查点失败时,继续往下执行。
    二、示例



    //
      int型比较,预期值:3,实际值:Add(1, 2)


    EXPECT_EQ(
    3
    , Add(
    1
    ,
    2
    ))

    //
      


    假如你的Add(1, 2) 结果为4的话,会在结果中输出:


    g:\myproject\c
    ++
    \gtestdemo\gtestdemo\gtestdemo.cpp(
    16
    ): error: Value of: Add(
    1
    ,
    2
    )
      Actual:
    4

    Expected:
    3


    如果是将结果输出到xml里的话,将输出:(关于将结果输出为xml,见:http://www.cnblogs.com/coderzh/archive/2009/04/10/1432789.html



    <
    testcase
    name
    ="Demo"
      status
    ="run"
      time
    ="0"
      classname
    ="AddTest"
    >

          
    <
    failure
    message
    ="Value of: Add(1, 2)  Actual: 4Expected: 3"
      type
    =""
    >
    <![CDATA[
    g:\myproject\c++\gtestdemo\gtestdemo\gtestdemo.cpp:16
    Value of: Add(1, 2)
      Actual: 4
    Expected: 3
    ]]>
    </
    failure
    >


    </
    testcase
    >


    如果你对自动输出的出错信息不满意的话,你还可以通过操作符<<将一些自定义的信息输出,通常,这对于调试或是对一些检查点的补充说明来说,非常有用!
    下面举个例子:

    如果不使用<<操作符自定义输出的话:



    for
      (
    int
      i
    =
      
    0
    ; i
    <
      x.size();
    ++
    i)
    {
        EXPECT_EQ(x, y)
    ;
    }


    看到的结果将是这样的,你根本不知道出错时 i 等于几:



    g:\myproject\c
    ++
    \gtestdemo\gtestdemo\gtestdemo.cpp(
    25
    ): error: Value of: y
      Actual:
    4

    Expected: x
    Which
    is
    :
    3


    如果使用<<操作符将一些重要信息输出的话:



    for
      (
    int
      i
    =
      
    0
    ; i
    <
      x.size();
    ++
    i)
    {
        EXPECT_EQ(x, y)
    <<
      
    "
    Vectors x and y differ at index
    "
      
    <<
      i;
    }



    从输出结果中就可以定位到在 i = 2 时出现了错误。这样的输出结果看起来更加有用,容易理解:


    g:\myproject\c
    ++
    \gtestdemo\gtestdemo\gtestdemo.cpp(
    25
    ): error: Value of: y
      Actual:
    4

    Expected: x
    Which
    is
    :
    3

    Vectors x and y differ at index
    2


    三、布尔值检查



       
       Fatal assertion  
        Nonfatal assertion  
        Verifies  
       
       
        ASSERT_TRUE(condition);  
        EXPECT_TRUE(condition);  
        condition is true  
       
       
        ASSERT_FALSE(condition);  
        EXPECT_FALSE(condition);  
        condition is false
      



    四、数值型数据检查




       
       Fatal assertion  
        Nonfatal assertion  
        Verifies  
       
       
       ASSERT_EQ(expected, actual);
       EXPECT_EQ(expected, actual);
        expected == actual  
       
       
       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
      



    五、字符串检查




       
       Fatal assertion  
        Nonfatal assertion  
        Verifies  
       
       
        ASSERT_STREQ(expected_str, actual_str);  
        EXPECT_STREQ(expected_str, actual_str);  
        the two C strings have the same content  
       
       
        ASSERT_STRNE(str1, str2);  
        EXPECT_STRNE(str1, str2);  
        the two C strings have different content  
       
       
        ASSERT_STRCASEEQ(expected_str, actual_str);
        EXPECT_STRCASEEQ(expected_str, actual_str);  
        the two C strings have the same content, ignoring case  
       
       
        ASSERT_STRCASENE(str1, str2);
        EXPECT_STRCASENE(str1, str2);  
        the two C strings have different content, ignoring case  
      



    *STREQ*和*STRNE*同时支持char*和wchar_t*类型的,*STRCASEEQ*和*STRCASENE*却只接收char*,估计是不常用吧。下面是几个例子:


    TEST(StringCmpTest, Demo)
    {
       
    char
    *
      pszCoderZh
    =
      
    "
    CoderZh
    "
    ;
        wchar_t
    *
      wszCoderZh
    =
      L
    "
    CoderZh
    "
    ;
        std::
    string
      strCoderZh
    =
      
    "
    CoderZh
    "
    ;
        std::wstring wstrCoderZh
    =
      L
    "
    CoderZh
    "
    ;

        EXPECT_STREQ(
    "
    CoderZh
    "
    , pszCoderZh);
        EXPECT_STREQ(L
    "
    CoderZh
    "
    , wszCoderZh);

        EXPECT_STRNE(
    "
    CnBlogs
    "
    , pszCoderZh);
        EXPECT_STRNE(L
    "
    CnBlogs
    "
    , wszCoderZh);

        EXPECT_STRCASEEQ(
    "
    coderzh
    "
    , pszCoderZh);
       
    //
    EXPECT_STRCASEEQ(L"coderzh", wszCoderZh);    不支持



        EXPECT_STREQ(
    "
    CoderZh
    "
    , strCoderZh.c_str());
        EXPECT_STREQ(L
    "
    CoderZh
    "
    , wstrCoderZh.c_str());
    }


    六、显示返回成功或失败

    直接返回成功:SUCCEED();
    返回失败:



       
       Fatal assertion  
        Nonfatal assertion  
       
       
        FAIL();  
        ADD_FAILURE();  
      





    TEST(ExplicitTest, Demo)
    {
        ADD_FAILURE()
    <<
      
    "
    Sorry
    "
    ;
    //
      None Fatal Asserton,继续往下执行。

       
    //
    FAIL();
    //
      Fatal Assertion,不往下执行该案例。



        SUCCEED();
    }


    七、异常检查




       
       Fatal assertion  
        Nonfatal assertion  
        Verifies  
       
       
        ASSERT_THROW(statement, exception_type);  
        EXPECT_THROW(statement, exception_type);  
        statement throws an exception of the given type  
       
       
        ASSERT_ANY_THROW(statement);  
        EXPECT_ANY_THROW(statement);  
        statement throws an exception of any type  
       
       
        ASSERT_NO_THROW(statement);  
        EXPECT_NO_THROW(statement);  
        statement doesn"t throw any exception  
      



    例如:


    int
      Foo(
    int
      a,
    int
      b)
    {
       
    if
      (a
    ==
      
    0
      
    ||
      b
    ==
      
    0
    )
        {
            
    throw
      
    "
    don"t do that
    "
    ;
        }
       
    int
      c
    =
      a
    %
      b;
       
    if
      (c
    ==
      
    0
    )
            
    return
      b;
       
    return
      Foo(b, c);
    }

    TEST(FooTest, HandleZeroInput)
    {
        EXPECT_ANY_THROW(Foo(
    10
    ,
    0
    ));
        EXPECT_THROW(Foo(
    0
    ,
    5
    ),
    char
    *
    );
    }


    八、Predicate Assertions
    在使用EXPECT_TRUE或ASSERT_TRUE时,有时希望能够输出更加详细的信息,比如检查一个函数的返回值TRUE还是FALSE时,希望能够输出传入的参数是什么,以便失败后好跟踪。因此提供了如下的断言:



       
       Fatal assertion  
        Nonfatal assertion  
        Verifies  
       
       
        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  
       
       
        ...  
        ...  
        ...  
      



    Google人说了,他们只提供<=5个参数的,如果需要测试更多的参数,直接告诉他们。下面看看这个东西怎么用。



    bool
      MutuallyPrime(
    int
      m,
    int
      n)
    {
       
    return
      Foo(m , n)
    >
      
    1
    ;
    }

    TEST(PredicateAssertionTest, Demo)
    {
       
    int
      m
    =
      
    5
    , n
    =
      
    6
    ;
        EXPECT_PRED2(MutuallyPrime, m, n);
    }


    当失败时,返回错误信息:
    error: MutuallyPrime(m, n) evaluates to false, where
    m evaluates to 5
    n evaluates to 6
    如果对这样的输出不满意的话,还可以自定义输出格式,通过如下:



       
       Fatal assertion  
        Nonfatal assertion  
        Verifies  
       
       
        ASSERT_PRED_FORMAT1(pred_format1, val1);`  
        EXPECT_PRED_FORMAT1(pred_format1, val1);  
        pred_format1(val1) is successful  
       
       
        ASSERT_PRED_FORMAT2(pred_format2, val1, val2);  
        EXPECT_PRED_FORMAT2(pred_format2, val1, val2);  
        pred_format2(val1, val2) is successful  
       
       
        ...  
        ...  
      



    用法示例:


    testing::AssertionResult AssertFoo(
    const
      
    char
    *
      m_expr,
    const
      
    char
    *
      n_expr,
    const
      
    char
    *
      k_expr,
    int
      m,
    int
      n,
    int
      k) {
       
    if
      (Foo(m, n)
    ==
      k)
            
    return
      testing::AssertionSuccess();
        testing::Message msg;
        msg
    <<
      m_expr
    <<
      
    "
      和
    "
      
    <<
      n_expr
    <<
      
    "
      的最大公约数应该是:
    "
      
    <<
      Foo(m, n)
    <<
      
    "
      而不是:
    "
      
    <<
      k_expr;
       
    return
      testing::AssertionFailure(msg);
    }

    TEST(AssertFooTest, HandleFail)
    {
        EXPECT_PRED_FORMAT3(AssertFoo,
    3
    ,
    6
    ,
    2
    );
    }


    失败时,输出信息:
    error: 3 和 6 的最大公约数应该是:3 而不是:2
    是不是更温馨呢,呵呵。

    九、浮点型检查




       
       Fatal assertion  
        Nonfatal assertion  
        Verifies  
       
       
        ASSERT_FLOAT_EQ(expected, actual);  
        EXPECT_FLOAT_EQ(expected, actual);  
        the two float values are almost equal  
       
       
        ASSERT_DOUBLE_EQ(expected, actual);  
        EXPECT_DOUBLE_EQ(expected, actual);  
        the two double values are almost equal  
      



    对相近的两个数比较:



       
       Fatal assertion  
        Nonfatal assertion  
        Verifies  
       
       
        ASSERT_NEAR(val1, val2, abs_error);  
        EXPECT_NEAR(val1, val2, abs_error);  
        the difference between val1 and val2 doesn"t exceed the given absolute error  
      



    同时,还可以使用:


    EXPECT_PRED_FORMAT2(testing::FloatLE, val1, val2);
    EXPECT_PRED_FORMAT2(testing::DoubleLE, val1, val2);


    十、Windows HRESULT assertions




       
       Fatal assertion  
        Nonfatal assertion  
        Verifies  
       
       
        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 HRESULT
      



    例如:


    CComPtr shell;
    ASSERT_HRESULT_SUCCEEDED(shell.CoCreateInstance(L
    "
    Shell.Application
    "
    ));
    CComVariant empty;
    ASSERT_HRESULT_SUCCEEDED(shell
    ->
    ShellExecute(CComBSTR(url), empty, empty, empty, empty));


    十一、类型检查
    类型检查失败时,直接导致代码编不过,难得用处就在这?看下面的例子:


    template
    <
    typename T
    >
      
    class
      FooType {

    public
    :
       
    void
      Bar() { testing::StaticAssertTypeEq
    <
    int
    , T
    >
    (); }
    };

    TEST(TypeAssertionTest, Demo)
    {
        FooType
    <
    bool
    >
      fooType;
        fooType.Bar();
    }


    十二、总结
    本篇将常用的断言都介绍了一遍,内容比较多,有些还是很有用的。要真的到写案例的时候,也行只是一两种是最常用的,现在时知道有这么多种选择,以后才方便查询。
    系列链接:
    1.玩转Google开源C++单元测试框架Google Test系列(gtest)之一 - 初识gtest
      
    2.玩转Google开源C++单元测试框架Google Test系列(gtest)之二 - 断言
      
    3.玩转Google开源C++单元测试框架Google Test系列(gtest)之三 - 事件机制
    4.玩转Google开源C++单元测试框架Google Test系列(gtest)之四 - 参数化  
    5.玩转Google开源C++单元测试框架Google Test系列(gtest)之五 - 死亡测试
      
    6.玩转Google开源C++单元测试框架Google Test系列(gtest)之六 - 运行参数  
    7.玩转Google开源C++单元测试框架Google Test系列(gtest)之七 - 深入解析gtest
      
    8.玩转Google开源C++单元测试框架Google Test系列(gtest)之八 - 打造自己的单元测试框架
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-4-20 22:07 , Processed in 0.432688 second(s), 46 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表