天天看点

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

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

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

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

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

EXPECT_EQ(3, Add(1, 2))

// 

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

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

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

  Actual: 4

Expected:3

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

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

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

Value of: Add(1, 2)

Expected: 3]]></failure>

</testcase>

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

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

下面举个例子:

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

for (int i = 0; i < x.size(); ++i)

{

    EXPECT_EQ(x[i], y[i]);

}

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

g:\myproject\c++\gtestdemo\gtestdemo\gtestdemo.cpp(25): error: Value of: y[i]

  Actual: 4

Expected: x[i]

Which is: 3

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

    EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i;

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

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

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

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

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

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());

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

直接返回成功:SUCCEED();

返回失败:

FAIL();

ADD_FAILURE();

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

TEST(ExplicitTest, Demo)

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

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

    SUCCEED();

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

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

例如:

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

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*);

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

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

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个参数的,如果需要测试更多的参数,直接告诉他们。下面看看这个东西怎么用。

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

bool MutuallyPrime(int m, int n)

    return Foo(m , n) > 1;

TEST(PredicateAssertionTest, Demo)

    int m = 5, n = 6;

    EXPECT_PRED2(MutuallyPrime, m, n);

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

当失败时,返回错误信息:

error: MutuallyPrime(m, n) evaluates to false, where

m evaluates to 5

n evaluates to 6

如果对这样的输出不满意的话,还可以自定义输出格式,通过如下:

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

用法示例:

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

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);

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

失败时,输出信息:

error: 3 和 6 的最大公约数应该是:3 而不是:2

是不是更温馨呢,呵呵。

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

对相近的两个数比较:

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);

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));

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

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

template <typename T> class FooType {

public:

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

};

TEST(TypeAssertionTest, Demo)

    FooType<bool> fooType;

    fooType.Bar();

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

 本篇将常用的断言都介绍了一遍,内容比较多,有些还是很有用的。要真的到写案例的时候,也行只是一两种是最常用的,现在时知道有这么多种选择,以后才方便查询。

系列链接:

<a href="http://www.cnblogs.com/coderzh/archive/2009/03/31/1426758.html">1.玩转Google开源C++单元测试框架Google Test系列(gtest)之一 - 初识gtest</a>

<a href="http://www.cnblogs.com/coderzh/archive/2009/04/06/1430364.html">2.玩转Google开源C++单元测试框架Google Test系列(gtest)之二 - 断言</a>

<a href="http://www.cnblogs.com/coderzh/archive/2009/04/06/1430396.html">3.玩转Google开源C++单元测试框架Google Test系列(gtest)之三 - 事件机制</a>

<a href="http://www.cnblogs.com/coderzh/archive/2009/04/08/1431297.html">4.玩转Google开源C++单元测试框架Google Test系列(gtest)之四 - 参数化</a>

<a href="http://www.cnblogs.com/coderzh/archive/2009/04/08/1432043.html">5.玩转Google开源C++单元测试框架Google Test系列(gtest)之五 - 死亡测试</a>

<a href="http://www.cnblogs.com/coderzh/archive/2009/04/10/1432789.html">6.玩转Google开源C++单元测试框架Google Test系列(gtest)之六 - 运行参数</a>

<a href="http://www.cnblogs.com/coderzh/archive/2009/04/11/1433744.html">7.玩转Google开源C++单元测试框架Google Test系列(gtest)之七 - 深入解析gtest</a>

<a href="http://www.cnblogs.com/coderzh/archive/2009/04/12/1434155.html">8.玩转Google开源C++单元测试框架Google Test系列(gtest)之八 - 打造自己的单元测试框架</a>

继续阅读