1

I am working on some code with unit tests using catch2 (and it will stay that way, for reasons).

Now, in the set of unit tests, there are a lot of (pairs of) lines which look like this:

  T t1;
  t1 = foo(some, params, here);
  CHECK(my_compare(t1, T{some_literal}));

so, my_out_param is being set using a single function call, and then it's compared to a T literal.

Now, when this runs and fails, I get:

/path/to/test.cpp:493: Failure:
  CHECK(my_compare(t1, T{some_literal}));
with expansion:
  false

but obviously I don't get the "some, params, here". Well, I need it. Otherwise, I don't really know which test failed without reading the source code.

Since there's a reliance on macros here, I can't just wrap CHECK() in a function and do something fancy inside.

What would you suggest I do to make "some, params, here" get printed alongside "some_literal" when the check fails, while:

  1. Keeping my test source code terse.
  2. Not repeating myself
  3. Still getting a valid file and line number

?

Note: The currently-used version of catch2 is 2.7.0, merged into a single header. If a version change would help, that may be doable.

einpoklum
  • 118,144
  • 57
  • 340
  • 684
  • I am surprised that support in Catch2 is so limited, boost test has a much better support for it https://www.boost.org/doc/libs/1_76_0/libs/test/doc/html/boost_test/testing_tools/boost_test_universal_macro.html I bookmarked this question. – Alessandro Teruzzi Jul 21 '21 at 14:50
  • @AlessandroTeruzzi: 1. It's quite possible that there's some catch2 mechanism for doing what I wanted 2. Actually, I have an inconsistency in my testcase code and the output, let me amend that slightly. It's not a proper equality check. – einpoklum Jul 21 '21 at 14:57
  • `CHECK(my_compare(t1= foo(some, params, here), T{some_literal}));` if you concern is assignation. – Jarod42 Jul 21 '21 at 15:01
  • 1
    [`CAPTURE`](https://github.com/catchorg/Catch2/blob/devel/docs/logging.md#quickly-capture-value-of-variables-or-expressions) seems promising too. – Jarod42 Jul 21 '21 at 15:10
  • @Jarod42: CAPTURE is not conditional on anything, IIANM. i.e. it will log stuff regardless of whether the check failed or not. But... that gives me an idea. – einpoklum Jul 21 '21 at 15:39
  • @einpoklum Sorry, but that's not true. `CAPTURE` like (`INFO` and `UNSCOPED_INFO`) writes output first to buffer and only outputs that buffer if the next assertion fails (see https://github.com/catchorg/Catch2/blob/devel/docs/logging.md#streaming-macros) – Elmar Zander Jul 13 '22 at 15:38

1 Answers1

0

Use the CAPTURE or INFO logging macros (see https://github.com/catchorg/Catch2/blob/devel/docs/logging.md#streaming-macros).

CAPTURE(some);
CAPTURE(params);
CAPTURE(here);

or

INFO("Params: some="<<some<<", params="<<params<<", here="<<here);

should do the trick.

BTW CAPTURE only logs variables that were captured in the same section as the failed test. Example:

    SECTION("foo"){
        int i = 1;
        CAPTURE(i);
        CHECK(i==1);
    }
    SECTION("bar"){
        int j = 2;
        CAPTURE(j);
        CHECK(j==1);
    }

outputs

foo.cpp:10: FAILED:
  CHECK( j==1 )
with expansion:
  2 == 1
with message:
  j := 2

Elmar Zander
  • 1,338
  • 17
  • 32