Home > The Unit Test Framework > Testing tools > Output testing tool
PrevNext

Output testing tool

How do you perform correctness test for operator<<( std::ostream&, ... ) operations? You can print into the standard output stream and manually check that it is matching your expectations. Unfortunately, this is not really acceptable for the regression testing and doesn't serve a ling term purpose of a unit test. You can use std::stringstream and compare resulting output buffer with the expected pattern string, but you are required to perform several additional operations with every check you do. So it becomes tedious very fast. The class output_test_stream is designed to automate these tasks for you. This is a simple, but powerful tool for testing standard std::ostream based output operation. The class output_test_stream complies to std::ostream interface so it can be used in place of any std::ostream parameter. It provides several test methods to validate output content, including test for match to expected output content or test for expected output length. Flushing, synchronizing, string comparison and error message generation is automated by the tool implementation.

In some cases it still may not be good enough. It becomes even more obvious when it's difficult to generate the expected pattern. What we need in cases like this is to be able to check once manually that the output is as expected and to be able in a future check that it stays the same. To help manage this logic the class output_test_stream allows matching output content versus specified pattern file and produce pattern file based on successful test run.

Detailed specification of class output_test_stream is covered in reference section.

Usage

There are two ways to employ the class output_test_stream: explicit output checks and pattern file matching.

Example34.output_test_stream usage with explicit output checks

Use the instance of class output_test_stream as an output stream and check output content using tool's methods. Note use of false to prevent output flushing in first two invocation of check functions. Unless you want to perform several different checks for the same output you wouldn't need to use it though. Your test will look like a serious of output operators followed by one check. And so on again. Try to perform checks as frequently as possible. It not only simplifies patterns you compare with, but also allows you to more closely identify possible source of failure.

#define BOOST_TEST_MODULE example
#include <boost/test/included/unit_test.hpp>
#include <boost/test/output_test_stream.hpp> 
using boost::test_tools::output_test_stream;

//____________________________________________________________________________//

BOOST_AUTO_TEST_CASE( test )
{
    output_test_stream output;
    int i=2;
    output << "i=" << i;
    BOOST_CHECK( !output.is_empty( false ) );
    BOOST_CHECK( output.check_length( 3, false ) );
    BOOST_CHECK( output.is_equal( "i=3" ) );
}

//____________________________________________________________________________//
Source code | Show output
> example
Running 1 test case...
test.cpp(15): error in "test": check output.is_equal( "i=3" ) failed. Output content: "i=2"

*** 1 failure detected in test suite "example"

Example35.output_test_stream usage for pattern file matching

Even simpler: no need to generate expected patterns. Though you need to keep the pattern file all the time somewhere around. Your testing will look like a serious of output operators followed by match pattern checks repeated several times. Try to perform checks as frequently as possible, because it allows you to more closely identify possible source of failure. Content of the pattern file is:

i=2
File:test.cppLine:14

#define BOOST_TEST_MODULE example
#include <boost/test/included/unit_test.hpp>
#include <boost/test/output_test_stream.hpp> 
using boost::test_tools::output_test_stream;

//____________________________________________________________________________//

BOOST_AUTO_TEST_CASE( test )
{
    output_test_stream output( "pattern_file", true );
    int i=2;
    output << "i=" << i;
    BOOST_CHECK( output.match_pattern() );

    output << "\nFile: " << __FILE__ << " Line: " << __LINE__;
    BOOST_CHECK( output.match_pattern() );
}

//____________________________________________________________________________//
Source code | Show output
> example
Running 1 test case...
test.cpp(16): error in "test": check output.match_pattern() failed. Mismatch at position 23
...5...
...4...

*** 1 failure detected in test suite "example"


PrevUpHomeNext