使用谷歌测试期望一个给定范围内的值

Expect a value within a given range using Google Test

本文关键字:一个 范围内 谷歌 测试 期望      更新时间:2023-10-16

我想指定一个期望值介于上限和下限之间,包括上限和下限。

谷歌测试提供了LT,LE,GT,GE,但没有办法测试我可以看到的范围。您可以使用EXPECT_NEAR并处理操作数,但在许多情况下,这并不像显式设置上限和下限那样清晰。

用法应类似于:

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

如何添加这种期望?

Google模拟比单独的 Google 测试具有更丰富的可组合匹配器:

#include "gmock/gmock.h"
using namespace ::testing;
// expect that x is >= 1 and <= 3
EXPECT_THAT(x, AllOf(Ge(1),Le(3)));

也许这对你有用。

请参阅"复合匹配器"部分下的googletestmatchers.md文档,此处

仅使用Google测试(不是模拟),那么简单,显而易见的答案是:

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

我发现这比一些基于模拟的答案更具可读性。

---开始编辑 --

上面的简单答案没有提供任何有用的诊断

可以使用AssertionResult来定义一个自定义断言,该断言确实会产生有用的错误消息,如下所示。

#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));
}

我会定义这些宏:

#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))

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

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));
}

最后,我创建了一个宏来执行此操作,该宏类似于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)

在谷歌测试中使用现有的布尔函数,不需要谷歌模拟。该链接非常具体。

下面是示例。

// 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;

断言EXPECT_PRED2(MutuallyPrime, a, b); 将成功,而 断言EXPECT_PRED2(互定,b,c);将失败,并显示 消息

!MutuallyPrime(b, c) is false, where
b is 4
c is 10

看看这里的答案,我真的认为最美丽和最完美的答案是多纳休@Billy和@Alexander沃伊坚科的答案之间的混合。

所以,这是我的建议。我认为这应该成为官方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)));用法是在多纳休@Billy在这里的回答中。
  2. https://github.com/google/googletest/blob/main/docs/reference/matchers.md
    1. 在"复合匹配器"部分下了解AllOf(m1, m2, ..., mn)复合匹配器
    2. 在"多参数匹配器"部分下了解Ge()("大于或等于")和Le()("小于或等于")匹配器