riddles
Riddle #6: Po**t
Focus is on a routine calculating a midpoint. Tests for other code is out of scope.
#include <gtest/gtest.h>

struct Point {
  int x, y;
};

bool operator==(const Point& lhs, const Point& rhs) {
  return (lhs.x == rhs.x) && (lhs.y == rhs.y);
}
// assume Point and its operator== have sufficient test coverage

Point midpoint(const Point& topLeft, const Point& bottomRight) {
  return Point{
    (topLeft.x + bottomRight.x) / 2,
    (topLeft.y + bottomRight.y) / 2};
}

TEST(PointTest, midpoint) {
  const Point topLeft{10, 20};
  const Point bottomRight{30, 40};
  
  EXPECT_EQ((Point{20, 30}), midpoint(topLeft, bottomRight));
}
#include <gtest/gtest.h>
#include <ostream>

struct Point {
  int x, y;
};

bool operator==(const Point& lhs, const Point& rhs) {
  return (lhs.x == rhs.x) && (lhs.y == rhs.y);
}
// assume Point and its operator== have sufficient test coverage

std::ostream& operator<<(std::ostream& os, const Point& p) {
  if (!os) return os;
  return os << "Point[x=" << p.x << ",y=" << p.y << ']';
}

Point midpoint(const Point& topLeft, const Point& bottomRight) {
  return Point{
    (topLeft.x + topLeft.x) / 2,
    (bottomRight.y + bottomRight.y) / 2};
}

TEST(PointTest, midpoint) {
  const Point topLeft{10, 20};
  const Point bottomRight{30, 40};
  
  EXPECT_EQ((Point{20, 30}), midpoint(topLeft, bottomRight));
}
#include <gtest/gtest.h>

struct Point {
  int x, y;
};

bool operator==(const Point& lhs, const Point& rhs) {
  return (lhs.x == rhs.x) && (lhs.y == rhs.y);
}
// assume Point and its operator== have sufficient test coverage

Point midpoint(const Point& topLeft, const Point& bottomRight) {
  return Point{
    (topLeft.x + topLeft.x) / 2,
    (bottomRight.y + bottomRight.y) / 2};
}

TEST(PointTest, midpoint) {
  const Point topLeft{10, 20};
  const Point bottomRight{30, 40};
  
  EXPECT_EQ((Point{20, 30}), midpoint(topLeft, bottomRight));
}
Can you spot a weakness in the test?
Give me a hint
What will happen in case of a test failure? Show me
Reveal the answer
Diagnosis
If the expectation fails, GTest will try to give as much information as it can. It will describe the entities that were expected to be equal:
[ RUN ] PointTest.midpoint test.cpp:22: Failure Expected equality of these values: (Point{20, 30}) Which is: 8-byte object <14-00 00-00 1E-00 00-00> midpoint(topLeft, bottomRight) Which is: 8-byte object <0A-00 00-00 28-00 00-00> [ FAILED ] PointTest.midpoint (1 ms)
In this simple case, the printed byte values still map to actual data in a pretty straightforward manner. However, in a more general case (struct having strings, optionals or pointers), such feedback is little helpful in diagnosing a failed test and one is forced to employ a debugger. We can't, however, blame GTest here, it can't do any better.
Reveal the remedy
Remedy
We can help GTest by adding the operator<< for the Point struct. Show me
Now the feedback from a failing test is a bit more helpful:
[ RUN ] PointTest.midpoint test.cpp:27: Failure Expected equality of these values: (Point{20, 30}) Which is: Point[x=20,y=30] midpoint(topLeft, bottomRight) Which is: Point[x=10,y=40] [ FAILED ] PointTest.midpoint (0 ms)
With such setup we receive more information from a failed test practically for free. It is often worth investing a moment in the output operator for your structs and even considering to place it in the production code, as next to enriching the test feedback it may also prove helpful in e.g. log statements.
Feedback on this riddle? 3c6120687265663d226d61696c746f3a666565646261636b407375737461696e61626c6563707074657374696e672e636f6d3f7375626a6563743d5375737461696e61626c6520432b2b2054657374696e672c20726964646c65233620666565646261636b223e446f2067657420696e20746f756368213c2f613e
<< Riddle #5: ABCDE || Riddle #7: Strategic >>