The acceptance test makes the customer satisfied that the
software provides the business value that makes them willing
to pay for it. The unit test makes the programmer satisfied
that the software does what the programmer thinks it does.
XP maxim
Introduction
Getting started
Usage
Components
The Test Case
The Test Suite
The Test Result
The Test Log
Configuration
Compilation
Example and test programs
See also: Test Tools
What is the first thing to do when you start working on new library/class/program? Exactly - you need the unit test module. There are many different sometime conflicting requirements programmers impose on a unit testing framework. Writing of the unit test module should be simple and obvious. On the other hand the framework should allow us to do a lot of nontrivial things. We want to be able to have a lot of small test cases and we want to be able to group them in test suites. At the beginning of the development we want to see as much descriptive error message as possible, while during regression testing we just want to know is there any errors at all. For small test programs a run time should prevail over a compilation time - who want to wait a 1 min to start the test that run a 1 sec?. For a long and complex test we want to be able to see the test progress.
The Boost Test Library's Unit Test Framework based on above rationale provides facilities to simplify writing test cases using Test Tools and organizing them into test suites hierarchy. The framework relieves users from messy a error detection, reporting duties and parameter processing. It provides function main() that initialize the framework, setups parameters based on command line arguments and/or environment variables, calls the user-supplied function init_unit_test_suite(argc, argv) and then runs the user's test suite. The framework keeps track of all passed/failed Test Tools assertions, provides an ability to check the testing progress based on the amount of test cases run as part of the total amount of test cases and generates the result report in several different formats. The Unit Test Framework intended to be used both for a simple testing needs and a complex non trivial testing. It is not intended to be used with the production code, where the Program Execution Monitor could be used. This was one of the design rationale to make the library implemented off-line vs. an inline implementation to allows us to speed up a compilation at an expense of a runtime efficiency. The Unit Test Framework consists of several cooperating components. All components are located in the namespace boost::unit_test.
As mentioned above the Unit Test Framework is responsible for supplying function main() that initializing testing environment and taking care about results reporting. The main function also includes a hook for the function that should be supplied by the user. So, to integrate test program with the framework you should provide the function with the following specification:
boost::unit_test::test_suite* init_unit_test_suite ( int argc, char* argv[] )
This function primary responsibility is to create and initialize test tree, that consists of test suites and test cases. In result it should return to the framework the top level instance of the class test_suite - master test suite. As an arguments to the init_unit_test_suite function the Unit Test Framework forwards command line arguments specified during test module invocation. It's guarantied that any framework-specific command line arguments are excluded. The NULL pointer returned by the function is treated as a non-initialized test tree - testing is not performed and a result code boost::exit_test_failure is returned by a test module. In the other case the framework starts testing from the master test suite level. The framework is responsible for the lifetime of master test suite. It gets destroyed at the end of test execution. If you are not using framework supplied mechanisms of test suite creation, make sure that the master test suite is allocated dynamically.
If you are using only zero arity free function based test cases, you could employ automatic registration facility, that allows to eliminate need in init_unit_test_suite and test cases registration. For more details see here.
In case if your test cases may throw custom exceptions (see here for list of exceptions translated by default), you could register translator specific for that exception. For more details on translator specification you could see excecution_monitor description. To register translator in test case monitor use following template function defined in the framework:
template<typename Exception, typename ExceptionTranslator>
void
boost::unit_test::register_exception_translator( ExceptionTranslator const& tr, boost::type<Exception>* d = 0 )
Once testing is finished, the framework reports the results and returns the result code. Here the list of values returned by the test programs integrated with the unit test framework:
Value | Meaning |
boost::exit_success | returned if no errors occurred during test or success result code was explicitly requested with the no result code framework parameter |
boost::exit_test_failure | returned if nonfatal errors detected and no uncaught exceptions thrown or the framework fails to initialize the test suite |
boost::exit_exception_failure | returned if fatal errors detected or uncaught exceptions thrown |
void my_test_function() { ... } test_suite* init_unit_test_suite( int argc, char* argv[] ) { test_suite* test = BOOST_TEST_SUITE( "Master test suite" ); test->add( BOOST_TEST_CASE( &my_test_function ) ); return test; }
unit_test_example1
unit_test_example2
unit_test_example3
unit_test_example4
unit_test_example5
test_case_template_example
online_test
errors_handling_test
parameterized_test_test
auto_unit_test_test
auto_unit_test_test_mult
custom_exception_test
test_case_template_test
result_report_test