Search code examples
c++unit-testingstdvectorstdarraycatch-unit-test

CATCH unit testing for C++ compare std::array


I like to use catch for my c++ unit tests. My goal is to compare std::array and std::vector. I created the this failing example.

#define CATCH_CONFIG_MAIN
#include "catch.hpp"

TEST_CASE("Vector") {
    std::vector<double> direction = {0.1, 0.3, 0.4};
    std::vector<double> false_direction = {0.1, 0.0, 0.4};
    REQUIRE(direction == false_direction);
}

TEST_CASE("Array") {
    std::array<double, 3> direction = {0.1, 0.3, 0.4};
    std::array<double, 3> false_direction = {0.1, 0.0, 0.4};
    REQUIRE(direction == false_direction);
}

The output of this test is for the check of std::vector

REQUIRE( direction == false_direction ) with expansion: { 0.1, 0.3, 0.4 } == { 0.1, 0.0, 0.4 }

and for std::array

REQUIRE( direction == false_direction ) with expansion: {?} == {?}

What can I do to display the actual and expected value? I like to have the very same display in a violated REQUIRE condition for std::array as for std::vector.

I use the latest version of catch (v1.10.0).


Solution

  • Fundamentally this is a question of how a type is stringified, and for that there is always the documentation.

    The abridged version is that there is a simple algorithm

    1. Check for specialization of Catch::StringMaker for given type. If exists, use it.

    2. Check for operator<< overload for given type. If exists, use it.

    3. Use "{?}".

    Until recently, Catch provided a specialization for std::vector out of the box, but not for std::array, because std::array was part of C++11 and generally less used. Since version 2.1.0 Catch instead checks whether the type provides a container-like interface, specifically, responds to begin(T) and end(T). This provides an automatic stringification for many different types, including std::vector, std::array, but also static arrays.