> The Unit Test Framework > Testing tools > 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.
There are two ways to employ the class output_test_stream
: explicit output checks and
pattern file matching.
Example 34. 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"
Example 35. 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.cpp Line: 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"