|  | Home | Libraries | People | FAQ | More | 
To test a template based component it's frequently necessary to perform the same set of checks for a component instantiated with different template parameters. The Unit Test Framework provides the ability to create a series of test cases based on a list of desired types and function similar to nullary function template. This facility is called test case template. Here are the two construction interfaces:
          To create a test case template registered in place of implementation, employ
          the macro BOOST_AUTO_TEST_CASE_TEMPLATE.
          This facility is also called auto test case template.
        
BOOST_AUTO_TEST_CASE_TEMPLATE(test_case_name, formal_type_parameter_name, collection_of_types);
          The macro BOOST_AUTO_TEST_CASE_TEMPLATE
          requires three arguments:
        
test_case_name The
              test case template name: unique test cases template identifier
            formal_type_parameter_name
              The name of a formal template parameter: name of the type the test
              case template is instantiated with
            | Code | 
|---|
| #define BOOST_TEST_MODULE example #include <boost/test/included/unit_test.hpp> #include <boost/mpl/list.hpp> typedef boost::mpl::list<int,long,unsigned char> test_types; BOOST_AUTO_TEST_CASE_TEMPLATE( my_test, T, test_types ) { BOOST_TEST( sizeof(T) == (unsigned)4 ); } | 
| Output | 
|---|
| > example Running 3 test cases... test.cpp(17): error: in "my_test<unsigned char>": check sizeof(T) == (unsigned)4 has failed [1 != 4] *** 1 failure is detected in the test module "example" | 
One way to perform the same set of checks for a component instantiated with different template parameters is illustrated in the following example:
template <typename T> void single_test() { BOOST_CHECK( /* test assertion */ ); } void combined_test() { single_test<int>(); single_test<float>(); single_test<unsigned char>(); }
There several problems/inconveniences with above approach, including:
          Ideally the test case template would be based on nullary function template
          (like single_test above). Unfortunately function templates are neither
          addressable nor can be used as template parameters. To alleviate the issue
          the manually registered test case template facility consists of two co-working
          macros: BOOST_TEST_CASE_TEMPLATE_FUNCTION
          and BOOST_TEST_CASE_TEMPLATE. Former
          is used to define the test case template body, later - to create and register
          test cases based on it.
        
          The macro BOOST_TEST_CASE_TEMPLATE_FUNCTION
          requires two arguments:
        
BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_case_name, type_name);
BOOST_TEST_CASE_TEMPLATE_FUNCTION( test_case_name, type_name ) { // test case template body }
          The macro BOOST_TEST_CASE_TEMPLATE_FUNCTION
          is intended to be used in place of nullary function template signature:
        
template <typename type_name> void test_case_name() { // test case template body }
          The only difference is that the BOOST_TEST_CASE_TEMPLATE_FUNCTION
          makes the test case template name usable in the template argument list.
        
          BOOST_TEST_CASE_TEMPLATE requires
          two arguments:
        
The names passed to both macros should be the same.
BOOST_TEST_CASE_TEMPLATE(test_case_name, collection_of_types);
          BOOST_TEST_CASE_TEMPLATE creates
          an instance of the test case generator. When passed to the method test_suite::add,
          the generator produces a separate sub test case for each type in the supplied
          collection of types and registers it immediately in the test suite. Each
          test case is based on the test case template body instantiated with a particular
          test type.
        
          The names for the sub test cases are deduced from
          the macro argument test_case_name.
          If you prefer to assign different test case names, you need to use the
          underlying make_test_case
          interface instead. Both test cases creation and registration is performed
          in the test module initialization function.
        
| ![[Tip]](../../../../../../../doc/src/images/tip.png) | Tip | 
|---|---|
| The test case template facility is preferable to the approach in example above, since execution of each sub test case is guarded and counted separately. It produces a better test log/results report (in example above in case of failure you can't say which type is at fault) and allows you to test all types even if one of them causes termination of the sub test case. | 
| Code | 
|---|
| #include <boost/test/included/unit_test.hpp> #include <boost/mpl/list.hpp> using namespace boost::unit_test; BOOST_TEST_CASE_TEMPLATE_FUNCTION( my_test, T ) { BOOST_TEST( sizeof(T) == 4U ); } test_suite* init_unit_test_suite( int /*argc*/, char* /*argv*/[] ) { typedef boost::mpl::list<int,long,unsigned char> test_types; framework::master_test_suite(). add( BOOST_TEST_CASE_TEMPLATE( my_test, test_types ) ); return 0; } | 
| Output | 
|---|
| > example Running 3 test cases... test.cpp(15): error: in "my_test<unsigned char>": check sizeof(T) == 4U has failed [1 != 4] *** 1 failure is detected in the test module "Master Test Suite" |