zoukankan      html  css  js  c++  java
  • gtest功能测试一

    一、前言

    这篇文章主要总结gtest中的所有断言相关的宏。 gtest中,断言的宏可以理解为分为两类,一类是ASSERT系列,一类是EXPECT系列。一个直观的解释就是:

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

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

    二、示例

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

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

    g:myprojectc++gtestdemogtestdemogtestdemo.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: 4 Expected: 3" type=""><![CDATA[g:myprojectc++gtestdemogtestdemogtestdemo.cpp:16
    Value of: Add(1, 2)
      Actual: 4
    Expected: 3]]></failure>
    </testcase>
    复制代码

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

    下面举个例子:

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

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


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

    g:myprojectc++gtestdemogtestdemogtestdemo.cpp(25): error: Value of: y[i]
      Actual: 4
    Expected: x[i]
    Which is: 3

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

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

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

    g:myprojectc++gtestdemogtestdemogtestdemo.cpp(25): error: Value of: y[i]
      Actual: 4
    Expected: x[i]
    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(expectedactual); EXPECT_EQ(expectedactual); expected == actual
    ASSERT_NE(val1val2); EXPECT_NE(val1val2); val1 != val2
    ASSERT_LT(val1val2); EXPECT_LT(val1val2); val1 < val2
    ASSERT_LE(val1val2); EXPECT_LE(val1val2); val1 <= val2
    ASSERT_GT(val1val2); EXPECT_GT(val1val2); val1 > val2
    ASSERT_GE(val1val2); EXPECT_GE(val1val2); val1 >= val2

    五、字符串检查 

    Fatal assertion Nonfatal assertion Verifies
    ASSERT_STREQ(expected_stractual_str); EXPECT_STREQ(expected_stractual_str); the two C strings have the same content
    ASSERT_STRNE(str1str2); EXPECT_STRNE(str1str2); 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(str1str2); EXPECT_STRCASENE(str1str2); 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(statementexception_type); EXPECT_THROW(statementexception_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)---位图的读写、几何变换、傅里叶变换、直方图均衡
    【C++】队列的实现
    【C++】一个简单栈的实现
    【Eclipse】Eclipse常用快捷键
    【Android】串口通信
    【Android SDK Manager】Android SDK Manager更新速度慢的一种解决方法
    class-dump 安装使用详解
    ios 给微信开发一个插件并安装到未越狱的手机上教程
    新建的亚马逊云服务器EC2 ping 不通 解决方案
    ubuntu服务器上提示 To run a command as administrator (user "root"), use "sudo <command>". See " 解决方案
  • 原文地址:https://www.cnblogs.com/oracleloyal/p/5179998.html
Copyright © 2011-2022 走看看