TA的每日心情 | 开心 2021-12-13 21:45 |
---|
签到天数: 15 天 [LV.4]偶尔看看III
|
一、前言
这篇文章主要总结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)之八 - 打造自己的单元测试框架
|
|