【问题标题】:c++ Google test (gtest): how to create custom asserts and expects?c++ Google 测试(gtest):如何创建自定义断言和期望?
【发布时间】:2017-07-21 14:27:18
【问题描述】:

我正在使用 gtest 为我的 c++ 程序创建单元测试。在我的测试中,我必须写很多这样的检查:

ASSERT_TRUE(myObject.IsValid());
EXPECT_EQ(myObject.GetSomeAttribute(), expectedValue);

我必须编写这两项检查,因为如果我省略 ASSERT_TRUE 和 myObject 碰巧无效,那么 myObject.GetSomeAttributre() 调用就会崩溃。即使在测试中也不好。

我想要的是写这样的东西:

EXPECT_XXX_EQ(myObject.GetSomeAttribute(), expectedValue);

这行代码应该和原来的两行大致相同(如果myObject 无效,则会报告此代码,GetSomeAttribute() 不会被调用,但测试将继续运行) .

如何编写这样的自定义断言/期望?

【问题讨论】:

  • Custom C++ assert macro的可能重复
  • 为什么不修复代码以检查对象在调用 getattribute 时是否有效?
  • @stark 两个原因:1. 我无法修改 GetSomeAttribute() 2. 即使我可以,如果调用无效对象,这种方法最好的方法就是死。
  • @Eddge 不是重复的; googletest 断言与标准 c++ 断言非常不同
  • 你没看the documentation吗?

标签: c++ unit-testing googletest


【解决方案1】:

从Advanced Guide,我们可以看到有几种方法可以做到这一点。

最简单的方法是using assertions in a subroutine:

template<typename T>
void AssertAttributeEquals(MyObject const& obj, T value) {
    ASSERT_TRUE(obj.IsValid());
    // googletest has the assumption that you put the
    // expected value first
    EXPECT_EQ(value, obj.GetAttribute());
}

你可以这样称呼它:

AssertAttributeEquals(myObject, expectedValue);

虽然您可能希望使用SCOPED_TRACE 来获得更好的失败消息:

{
    SCOPED_TRACE("whatever message you want");
    AssertAttributeEquals(myObject, expectedValue);
}

您也可以use a function that returns an AssertionResult:

template<typename T>
::testing::AssertionResult AttributeEquals(MyObject const& obj, T value) {
    if (!obj.IsValid()) {
        // If MyObject is streamable, then we probably want to include it
        // in the error message.
        return ::testing::AssertionFailure() << obj << " is not valid";
    }
    auto attr = obj.GetAttribute();

    if (attr == value) {
        return ::testing::AssertionSuccess();
    } else {
        return ::testing::AssertionFailure() << attr << " not equal to " << value;
    }
}

可以这样使用:

EXPECT_TRUE(AttributeEquals(myObject, expectedValue));

即使您不使用SCOPED_TRACE,第二种技术的好处是可以生成漂亮的错误消息

【讨论】:

  • 函数的缺点是,如果发生故障,报告的源代码行在函数内部,而不是调用函数的位置。这使得更难看出究竟是哪里出了问题。
  • SCOPED_TRACE 可以提供帮助,但需要编写额外的代码。 (不得不创建一个新评论,因为我编辑的速度不够快)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多