c++ 使用GoogleTest预期给定范围内的值

ukxgm1gy  于 2023-03-20  发布在  Go
关注(0)|答案(7)|浏览(151)

我想指定一个期望值,即一个值介于上界和下界之间,包括上界和下界。
Google Test提供了LT、LE、GT、GE,但我看不到测试范围的方法。您可以使用EXPECT_NEAR并调整操作数,但在许多情况下,这并不像显式设置上下限那样清晰。
用法应类似于:

EXPECT_WITHIN_INCLUSIVE(1, 3, 2); // 2 is in range [1,3]

如何增加这种期望呢?

bnlyeluc

bnlyeluc1#

Google Mock拥有比Google Test更丰富的组合匹配器:

#include "gmock/gmock.h"

using namespace ::testing;

// expect that x is >= 1 and <= 3
EXPECT_THAT(x, AllOf(Ge(1),Le(3)));

也许这对你有用。
请参阅“复合匹配器”部分下的googletest matchers.md文档,此处

stszievb

stszievb2#

只使用Google Test(而不是mock),那么简单、明显的答案是:

EXPECT_TRUE((a >= 1) && (a <= 3)); // a is between 1 and 3 inclusive

我发现这比一些基于模拟的答案更具可读性。
---开始编辑--
上面的简单答案没有提供任何有用的诊断
您可以使用AssertionResult定义一个自定义Assert,该Assert确实会产生如下有用的错误消息。

#include <gtest/gtest.h>

::testing::AssertionResult IsBetweenInclusive(int val, int a, int b)
{
    if((val >= a) && (val <= b))
        return ::testing::AssertionSuccess();
    else
        return ::testing::AssertionFailure()
               << val << " is outside the range " << a << " to " << b;
}

TEST(testing, TestPass)
{
    auto a = 2;
    EXPECT_TRUE(IsBetweenInclusive(a, 1, 3));
}

TEST(testing, TestFail)
{
    auto a = 5;
    EXPECT_TRUE(IsBetweenInclusive(a, 1, 3));
}
irlmq6kh

irlmq6kh3#

我将定义这些宏:

#define EXPECT_IN_RANGE(VAL, MIN, MAX) \
    EXPECT_GE((VAL), (MIN));           \
    EXPECT_LE((VAL), (MAX))

#define ASSERT_IN_RANGE(VAL, MIN, MAX) \
    ASSERT_GE((VAL), (MIN));           \
    ASSERT_LE((VAL), (MAX))
wgx48brx

wgx48brx4#

谷歌模拟备忘单中有一个很好的例子:

using namespace testing;
MATCHER_P2(IsBetween, a, b,
           std::string(negation ? "isn't" : "is") + " between " + PrintToString(a)
           + " and " + PrintToString(b))
{
    return a <= arg && arg <= b;
}

然后使用它:

TEST(MyTest, Name) {
    EXPECT_THAT(42, IsBetween(40, 46));
}
gtlvzcf8

gtlvzcf85#

最后,我创建了一个宏来执行此操作,该宏类似于Google测试库中的其他宏。

#define EXPECT_WITHIN_INCLUSIVE(lower, upper, val) \
  do { \
    EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperGE, val, lower); \
    EXPECT_PRED_FORMAT2(::testing::internal::CmpHelperLE, val, upper); \
  } while (0)
zpf6vheq

zpf6vheq6#

在谷歌测试中使用现有的布尔函数,不需要谷歌模拟。链接是相当具体的。
下面是一个例子。

// Returns true iff m and n have no common divisors except 1.
bool MutuallyPrime(int m, int n) { ... }
const int a = 3;
const int b = 4;
const int c = 10;

Assert预期预测2(互素,a,B);将成功,而AssertEXPECT_PRED2(互素,B,c);将失败并显示消息

!MutuallyPrime(b, c) is false, where

b is 4

c is 10
daupos2t

daupos2t7#

看看这里的答案,我真的认为最美丽和完美的答案是“比利·多纳休的答案”和“ Alexandria ·沃伊坚科的答案”的结合。
所以,我的建议是,我认为这应该成为googletest/googlemock官方代码库的一部分:

快速总结

// 1. definitions
#define EXPECT_RANGE(val, min, max) EXPECT_THAT((val), \
    ::testing::AllOf(::testing::Ge((min)), ::testing::Le((max))))
#define ASSERT_RANGE(val, min, max) ASSERT_THAT((val), \
    ::testing::AllOf(::testing::Ge((min)), ::testing::Le((max))))

// 2. usage
EXPECT_RANGE(value, min, max);
ASSERT_RANGE(value, min, max);

详情

下面是更完整的描述:

#include "gmock/gmock.h"

/// Expect or assert that value `val` is within the range of `min` to `max`, 
/// inclusive. ie: `val` is tested to be >= `min` and <= `max`.
/// See:
/// 1. googletest `matchers.md` document under the "Composite Matchers" section, 
///    here:
///    https://github.com/google/googletest/blob/main/docs/reference/matchers.md#composite-matchers
/// 1. [My answer with this code] https://stackoverflow.com/a/75786774/4561887
#define EXPECT_RANGE(val, min, max) EXPECT_THAT((val), \
    ::testing::AllOf(::testing::Ge((min)), ::testing::Le((max))))
#define ASSERT_RANGE(val, min, max) ASSERT_THAT((val), \
    ::testing::AllOf(::testing::Ge((min)), ::testing::Le((max))))

TEST(Simulation, TrivialEndToEnd)
{
    // ...test setup stuff goes here...

    // Usage example: expect that the `distance_traveled_miles` value is within
    // the range 1151.77 to 1151.97, inclusive.
    EXPECT_RANGE(stats->distance_traveled_miles, 1151.77, 1151.97);
}

测试失败时的错误输出也很不错,下面是测试失败时打印的内容:

src/main_unittest.cpp:194: Failure
Value of: (stats->distance_traveled_miles)
Expected: (is >= 1151.77) and (is <= 1151.97)
  Actual: 1151.6666666667204 (of type double)
[  FAILED  ] Simulation.TrivialEndToEnd (0 ms)

如果需要,还可以使用<<输出打印操作符将C++样式的打印添加到错误消息中,如下所示:

EXPECT_RANGE(stats->distance_traveled_miles, 1151.77, 1151.97) 
    << "Your custom failure message goes here.\n";

如果发生故障,上一行将生成以下输出:

src/main_unittest.cpp:194: Failure
Value of: (stats->distance_traveled_miles)
Expected: (is >= 1151.77) and (is <= 1151.97)
  Actual: 1151.6666666667204 (of type double)
Your custom failure message goes here.

[  FAILED  ] Simulation.TrivialEndToEnd (0 ms)

参考文献:

1.我第一次看到EXPECT_THAT(x, AllOf(Ge(1),Le(3)));的用法in @Billy Donahue's answer here

  1. https://github.com/google/googletest/blob/main/docs/reference/matchers.md
    1.在“Composite Matchers”一节中了解AllOf(m1, m2, ..., mn)复合匹配器
    1.在“多参数匹配器”部分了解Ge()(“大于或等于”)和Le()(“小于或等于”)匹配器

相关问题