c++unit-testingboost-testoutput-formattingcatch2

Controlling output of Boost.Test source location format


Catch2 and Boost.Test provide similar features for writing unit tests. For a certain project I have to use Boost.Test instead of Catch2. The problem I have is that both use different format outputs.

For example, Catch2 will say that the was a fail in

test.cpp:9

(see example below). However Boost.Test will say

test.cpp(9): error in ....

This format doesn't allow my editor to recognize the output as a source location.

Is there way to make Boost.Test output the source location as file.ext:lineno instead of file.ext(lineno)?

This is a typical output for Catch2

----------------------------------------------
Testing Binary Search
----------------------------------------------
test.cpp:9
..............................................test.cpp:18: FAILED:
  REQUIRE( binary_search(arr, 176) == 0 )
with expansion:
  -1 == 0==============================================
test cases: 1 | 1 failed
assertions: 5 | 4 passed | 1 failed

This is a typical output for Boost.Test

Running 7 test cases...
./layout.hpp(764): error: in "layout_to_offset_1d_nontrivial": check L[3] == &B[3] - base(B) has failed [3 != 6]
Running 7 test cases...
./.././detail/layout.hpp(764): error: in "layout_to_offset_1d_nontrivial": check L[3] == &B[3] - base(B) has failed [3 != 6]

*** 1 failure is detected in the test module "C++ Unit Tests for Multi layout"

Solution

  • I found a solution in this historical post: https://richarddingwall.name/2008/06/01/using-the-boost-unit-test-framework-with-xcode-3

    Using the (lost of) art of virtual function override and Boost.Test fixtures:

    Simply add this code (some updates to the original post, with minor formats and C++11 updates):

    #include<boost/test/output/compiler_log_formatter.hpp>
    
    struct xcode_log_formatter: boost::unit_test::output::compiler_log_formatter{
        // Produces an Xcode-friendly message prefix.
        void print_prefix(std::ostream& output, boost::unit_test::const_string file_name, std::size_t line) override{
            output << file_name << ':' << line << ": error: ";
        }
    };
    
    // Set up the unit test framework to use an xcode-friendly log formatter.
    struct xcode_config{
        xcode_config(){boost::unit_test::unit_test_log.set_formatter(new xcode_log_formatter);}
    };
    
    // Call our fixture.
    BOOST_GLOBAL_FIXTURE(xcode_config);
    

    with this change the output looks like (note file:lineno format).

    Running 7 test cases...
    ./layout.hpp:781: error: error: in "layout_to_offset_1d_nontrivial": check L[3] == &B[3] - base(B) has failed [3 != 6]
    Running 7 test cases...
    ./.././detail/layout.hpp:781: error: error: in "layout_to_offset_1d_nontrivial": check L[3] == &B[3] - base(B) has failed [3 != 6]
    

    I am still interested in simpler solutions.


    Here it is a more compact version of this code, renamed for my own case (xcode->gedit):

    #include<boost/test/output/compiler_log_formatter.hpp>
    struct gedit_config{
        struct formatter : boost::unit_test::output::compiler_log_formatter{
            void print_prefix(std::ostream& out, boost::unit_test::const_string file, std::size_t line){
                out<< file <<':'<< line <<": ";
            }
        };
        gedit_config(){boost::unit_test::unit_test_log.set_formatter(new formatter);}
    };
    BOOST_GLOBAL_FIXTURE(gedit_config);