Custom EXPECT_NEAR macro in Google Test
Asked Answered
M

2

8

Scope: Using Google Test and OpenCV.

I'd like to test that my Vec3f equals another Vec3f. Vec3f is a vector in OpenCV of dimension 3 and type float. The ==-operator is defined, so EXPECT_EQ(Vec3f(), Vec3f()) works.

But as they are floats, I'd like to use the EXPECT_NEAR(float a, float b, float delta) macro. What can I do so that I can use it like EXPECT_NEAR(vec_a, vec_b, float delta)?

At the moment I am looping through each element of the vector and doing an EXPECT_NEAR there.

This might be related: Convenient method in GoogleTest for a double comparison of not equal?

Murton answered 19/8, 2011 at 11:13 Comment(0)
T
4

You are doing basically the correct thing. However, I would use a custom assertion function like:

::testing::AssertionResult AreAllElementsInVectorNear(const Vec3f& a, const Vect3f& b, float delta) {
  if ([MAGIC])
    return ::testing::AssertionSuccess();
  else
    return ::testing::AssertionFailure() << "Vectors differ by more than " << delta;
}

MAGIC would then include your code to e.g. compare if both vectors have the same size, followed by iterating over all elements and mutually check if the elements at the same index differ by no more than the delta. Note that the code assumes that the << operator is provided for Vec3f.

The function then is used:

EXPECT_TRUE(AreAllElementsInVectorNear(a, b, 0.1))

If the expect fails the output might be:

Value of: AreAllElementsInVectorNear(a, b, 0.1)
  Actual: false (Vectors differ by more then 0.1)
Expected: true
Troat answered 19/8, 2011 at 12:46 Comment(0)
M
11

You can use the Pointwise() matcher from Google Mock. Combine it with a custom matcher that checks that the two arguments are near:

#include <gmock/gmock.h>

using testing::Pointwise;

MATCHER_P(NearWithPrecision, precision, "") {
  return std::abs(std::get<0>(arg) - std::get<1>(arg)) < precision;
}

TEST(FooTest, ArraysNear) {
  EXPECT_THAT(result_array, Pointwise(NearWithPrecision(0.1), expected_array));
}
Maestricht answered 20/8, 2011 at 0:52 Comment(0)
T
4

You are doing basically the correct thing. However, I would use a custom assertion function like:

::testing::AssertionResult AreAllElementsInVectorNear(const Vec3f& a, const Vect3f& b, float delta) {
  if ([MAGIC])
    return ::testing::AssertionSuccess();
  else
    return ::testing::AssertionFailure() << "Vectors differ by more than " << delta;
}

MAGIC would then include your code to e.g. compare if both vectors have the same size, followed by iterating over all elements and mutually check if the elements at the same index differ by no more than the delta. Note that the code assumes that the << operator is provided for Vec3f.

The function then is used:

EXPECT_TRUE(AreAllElementsInVectorNear(a, b, 0.1))

If the expect fails the output might be:

Value of: AreAllElementsInVectorNear(a, b, 0.1)
  Actual: false (Vectors differ by more then 0.1)
Expected: true
Troat answered 19/8, 2011 at 12:46 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.