前言
我们在上一篇文章中,简要介绍了gtest是如何使用的
单元测试框架gtest学习(一)——初始gtest-CSDN博客
这篇文章我们主要总结gtest中的所有断言相关的宏。首先需要明确的是,gtest是通过各种断言宏进行测试的,而这些断言的宏可以为分为两类,一类是ASSERT系列,一类是EXPECT系列。一个直观的解释就是:
1. ASSERT_* 系列的断言,当检查点失败时,退出当前函数(注意:并非退出当前案例)。
2. EXPECT_* 系列的断言,当检查点失败时,继续往下执行。
一般情况下,我们使用EXPECT_*系列的断言宏较多
示例
// int型比较,预期值:3,实际值:Add(1, 2)
EXPECT_EQ(3, Add(1, 2))
假如你的Add(1, 2) 结果为4的话,会在结果中输出:
Actual: 4
Expected:3
此外,我们还可以自定义输出信息,如下所示,我们编写一个测试案例
std::vector<int> x = {1, 2, 3, 4};
std::vector<int> y = {1, 2, 4, 4};
TEST(VectorTest, demo) {
for (int i = 0; i < x.size(); ++i) {
EXPECT_EQ(x[i], y[i]) << "Vectors x and y differ at index " << i;
}
}
该测试案例很简单,表示我测试x和y两个vector中的数值是否正确,如果测试失败,会输出一些我们自定义的信息
编译运行上述代码
g++ ./gTest.cc -o gtest -std=c++14 -lgtest -lpthread -lgtest_main
可以看到,在测试失败的详细信息里,gtest给出了测试失败的具体信息,比如
- 在代码20行测试失败
- 失败的原因是x中的某一个索引下的值为3,而y中的某一个索引下的值为4
- 而最后一行的具体出错的索引信息是我们自定义的(可以想到,如果我们没有这条自定义信息,那么gtest不会详细输出具体的出错索引位置)
./gTest.cc:20: Failure
Expected equality of these values:
x[i]
Which is: 3
y[i]
Which is: 4
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 |
bool isEven(int n) { return n % 2 == 0; }
TEST(BooleanTest, CheckEven) {
ASSERT_TRUE(isEven(4)); // 4 是偶数,应该通过
EXPECT_FALSE(isEven(5)); // 5 不是偶数,应该失败
}
数值型数据检查
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_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);
字符串检查
Fatal assertion | Nonfatal assertion | Verifies |
---|---|---|
ASSERT_STREQ (expected_str, actual_str) | EXPECT_STREQ (expected_str, actual_str); | 判断字符串是否相等 |
ASSERT_STRNE(str1, str2); | EXPECT_STRNE(str1, str2); | 判断两个字符串是否不等 |
ASSERT_STRCASEEQ (expected_str, actual_str) | EXPECT_STRCASEEQ (expected_str, actual_str) | 判断两个字符串是否相等,同时忽略大小写 |
ASSERT_STRCASENE(str1, str2) | EXPECT_STRCASENE(str1, str2) | 判断两个字符串是否不等,同时忽略大小写 |
需要注意,*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(); |
异常检查
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));
//期望抛出一个char *的异常
EXPECT_THROW(Foo(0, 5), char *);
}
EXPECT_ANY_THROW(Foo(10, 0));
:
- 这行代码测试当
Foo
函数的第二个参数为0
时,是否会抛出一个异常。- 由于在
Foo
函数中,如果b == 0
,会抛出一个const char*
类型的异常"don't do that"
,所以这行代码期望函数抛出任何类型的异常(EXPECT_ANY_THROW
).- 该测试期望在执行
Foo(10, 0)
时抛出异常。
EXPECT_THROW(Foo(0, 5), char *);
:
- 这行代码测试当
Foo
函数的第一个参数为0
时,是否抛出一个特定类型的异常,即const char*
类型的异常。- 在
Foo
函数中,如果a == 0
,也会抛出一个const char*
类型的异常"don't do that"
,因此这行代码期望抛出一个类型为const char*
的异常。EXPECT_THROW(Foo(0, 5), char *)
期望Foo(0, 5)
执行时抛出char*
类型的异常。