Boost C++ Libraries of the most highly regarded and expertly designed C++ library projects in the world. Herb Sutter and Andrei Alexandrescu, C++ Coding Standards


Logging user defined types

Most of the testing tools print values of their arguments to the output stream in some form of log statement. If arguments type does not support

operator<<(std::ostream&, ArgumentType const&);

interface, you will get a compilation error.

The Unit Test Framework supports three different methods for logging user defined types:

  1. through the operator<< for that specific type: any type that implements the above interface has direct support for logging,
  2. through a customization point responsible for logging a specific type, which is less intrusive than the implementation of operator<<. This is explained in more details in this section,
  3. by prohibiting the testing tools from logging argument values for specified type through BOOST_TEST_DONT_PRINT_LOG_VALUE. This is explained in more details in this section.
User type customization point for logging

It is possible to indicate a function, boost_test_print_type, to Unit Test Framework that is responsible for the printing of a user defined type, without the need to override the operator<< for that specific type. This is convenient for instance when the operator<< has already been defined for other needs.

The syntax follows the operator<<, and this function should be in the same namespace as the type:

std::ostream& boost_test_print_type(std::ostream& ostr, ArgumentType const& right);
Example: Logging customization point usage


#define BOOST_TEST_MODULE logger-customization-point
#include <boost/test/included/unit_test.hpp>

namespace user_defined_namespace {
  struct user_defined_type {
      int value;

      user_defined_type(int value_) : value(value_)

      bool operator==(int right) const {
          return right == value;

namespace user_defined_namespace {
  std::ostream& boost_test_print_type(std::ostream& ostr, user_defined_type const& right) {
      ostr << "** value of user_defined_type is " << right.value << " **";
      return ostr;

    user_defined_namespace::user_defined_type t(10);
    BOOST_TEST(t == 11);

    using namespace user_defined_namespace;
    user_defined_type t2(11);
    BOOST_TEST(t2 == 11);


> logger-customization-point --log_level=all
Running 1 test case...
Entering test module "logger-customization-point"
test.cpp(36): Entering test case "test1"
test.cpp(39): error: in "test1": check t == 11 has failed [** value of user_defined_type is 10 ** != 11]
test.cpp(43): info: check t2 == 11 has passed
test.cpp(36): Leaving test case "test1"; testing time: 125us
Leaving test module "logger-example-customization-point"; testing time: 157us

*** 1 failure is detected in the test module "logger-customization-point"
Prohibiting the printing of a specific type

To prohibit the printing of a specific type, use the following statement on file level before first test case that includes statement failing to compile:



#define BOOST_TEST_MODULE example
#include <boost/test/included/unit_test.hpp>
#include <utility>

typedef std::pair<int,float> pair_type;


  pair_type p1( 2, 5.5f );
  pair_type p2( 2, 5.501f );

  BOOST_CHECK_EQUAL( p1, p2 );


Running 1 test case...
test.cpp(16): error in "test_list": check p1 == p2 has failed [ != ]

*** 1 failures is detected in test suite "example"