自学内容网 自学内容网

单元测试框架gtest学习(二)—— 认识断言

前言

我们在上一篇文章中,简要介绍了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 assertionNonfatal assertionVerifies
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 assertionNonfatal assertionVerifies
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 assertionNonfatal assertionVerifies
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 assertionNonfatal assertionVerifies
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 assertionNonfatal assertionVerifies
ASSERT_STREQ
(expected_stractual_str)
EXPECT_STREQ
(expected_stractual_str);
判断字符串是否相等
ASSERT_STRNE(str1str2);EXPECT_STRNE(str1str2);判断两个字符串是否不等
ASSERT_STRCASEEQ
(expected_stractual_str)
EXPECT_STRCASEEQ
(expected_stractual_str)
判断两个字符串是否相等,同时忽略大小写
ASSERT_STRCASENE(str1str2)EXPECT_STRCASENE(str1str2)判断两个字符串是否不等,同时忽略大小写

需要注意,*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 assertionNonfatal assertion
FAIL();ADD_FAILURE();

异常检查

Fatal assertionNonfatal assertionVerifies
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));
    //期望抛出一个char *的异常
    EXPECT_THROW(Foo(0, 5), char *);
}
  1. EXPECT_ANY_THROW(Foo(10, 0));:

    • 这行代码测试当 Foo 函数的第二个参数为 0 时,是否会抛出一个异常。
    • 由于在 Foo 函数中,如果 b == 0,会抛出一个 const char* 类型的异常 "don't do that",所以这行代码期望函数抛出任何类型的异常(EXPECT_ANY_THROW).
    • 该测试期望在执行 Foo(10, 0) 时抛出异常。
  2. 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* 类型的异常。


原文地址:https://blog.csdn.net/qq_58158950/article/details/143926509

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!