Login Status


ShareSource Site » Projects » test_o_matic » test_o_maticWiki

Project: test-o-matic [Wiki]

(*) Summary   [^] Files   [_] Wiki   [!] Bug Tracker   (») Mercurial Repository  
Project Wiki (Page: Customising_output)
Last Changed 1 year ago, by Edd

Customising output

All output written by test-o-matic is done through a test_o_matic::logger object.

The macros supplied by test-o-matic call in to a logger to tell it about events that occur while the tests are running.

By defining your own event handlers and registering them with a logger, you can respond to events in anyway you like, including of course writing formatted output to the console.

The anatomy of an event handler

A test-o-matic event handler is any function or functor with a signature compatible with the following:

stats f(strmap kv, stats st);

stats and strmap both live in the test_o_matic namespace.

stats is a simple struct with four size_t members: successes, failures, complete and aborted.

successes and failures are used to count the number of individual checks that pass or fail. complete and aborted are used to track the number of tests that finish normally or abnormally (i.e. with an ABORT() or similar).

strmap is a typedef for std::map<std::string, std::string>.

An event handler must deal with the information in kv (which can be thought of as a bunch of key-value pairs) and return an updated version of the stats object.

So a simple event handler might look like this:

stats my_handler(strmap kv, stats st)
{
    if (kv["result"] == "ok")
    {
        std::cout << "HURRAH!\n";
        std::cout << "Test on line " << kv["line"] << " passed!\n";
        ++st.successes;
    }
    else
    {
        ++st.failures;
    }
    return st;
}

Don't forget that you can also use functors for event handlers i.e. objects with overloaded operator(), allowing them to store and manipulate local state if need be.

Once you've defined your handler you can register it with a logger object for a particular event:

logger lgr;
lgr.add_handler("check", &my_handler);

The CHECK() macro supplied with test-o-matic triggers the "check" event to report success or failure. Events are triggered by calling the record() member function of a logger.

strmap keys set by test-o-matic macros

To write a handler properly, you'll need to know the key/value pairs each test-o-matic macro sets in the strmap passed to the handlers, and the names of events against which to register your handlers.

If you're ever in doubt, have a look at the implementation of the default_logger() function in test_o_matic.cpp

CATCH(), REQUIRE(), TRY() and THROWS() all set values for these keys:

  • line: the line number of the macro invocation
  • file: the file in which the invocation resides
  • statement: the argument passed to the macro
  • result: contains either "ok" or "fail".
  • threw: contains information on what was thrown, if anything e.g:
    • "an exception"
    • "an exception unexpectedly"
    • "an exception of type 'XYZ'"
    • "a different type of exception than 'ABC'"
    • "nothing"

Also, by the time the strmap reaches your handler, it will have an event key whose corresponding value contains the name of the event that triggered the handler.

The REQUIRE macro will always trigger a check event. In addition, if the check fails, a post_test event will be triggered. Values for the following keys will be present in the strmap argument passed to the handler:

  • all those present in the corresponding check event
  • reason: contains "REQUIRE()ment '<statement>' not met", where <statement> is the argument passed to the macro.

The ABORT() macro will trigger a post_test event. The strmap will contain the usual file and line keys and also:

  • result: contains "aborted"
  • reason: contains "test ABORT()ed"

A post_test event will also get triggered by the default runner object supplied by test-o-matic if an exception ends the test. In this case, values for the following keys will be present:

  • result: contains "aborted"
  • reason: contains "an uncaught exception ended the test"

If the test ends normally, a post_test event will be triggered containing only a single key result with the value "ok".

There is also a pre_test event, again triggered by the default runner. This submits an strmap containing values for the following keys:

  • name: the name of the test about to be run
  • line: the line on which the test definition begins
  • file: the file in which the test definition resides
  • date: the date the test was compiled
  • time: the time the test was compiled

Don't forget that your event handler for post_test should update either the complete or the aborted member of the stats argument before returning it.

Default handlers

By default, a test_o_matic::logger object is empty; it has no handlers what-so-ever. If you want to start with a blank slate, then add your handlers to a default constructed {logger:

test_o_matic::logger lgr;
lgr.add_handler("check", my_check_handler);
// ...

Alternatively, you can start with a copy of the logger returned by test_o_matic::default_logger():

test_o_matic::logger lgr = test_o_matic::default_logger();
lgr.add_handler("check", my_check_handler);
// ...

If you register a handler with a logger for an event that already has an associated handler, the previous handler will be overwritten.