typed_parametrized_tests.qbk 6.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  1. [/
  2. / Copyright (c) 2003 Boost.Test contributors
  3. /
  4. / Distributed under the Boost Software License, Version 1.0. (See accompanying
  5. / file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
  6. /]
  7. [section:test_organization_templates Template test cases]
  8. In order to test a template based component, it is frequently necessary to perform the same set of checks for a
  9. component instantiated with different template parameters.
  10. One way to perform the same set of checks for a component instantiated with different template parameters would be:
  11. ``
  12. template <typename T>
  13. void single_test()
  14. {
  15. BOOST_CHECK( /* test assertion */ );
  16. }
  17. void combined_test()
  18. {
  19. single_test<int>();
  20. single_test<float>();
  21. single_test<unsigned char>();
  22. }
  23. ``
  24. There several problems/inconveniences with above approach, including:
  25. * Fatal error in one of the invocation will stop whole test case and will skip invocations with different types
  26. * You need to repeat function invocation manually for all the parameters you are interested in
  27. * You need two functions to implement the test
  28. The __UTF__ provides a facility, the *template test case*, to create a series of
  29. test cases based on a list of desired types and /nullary/ function. This facility comes with an
  30. [link ref_BOOST_AUTO_TEST_CASE_TEMPLATE automatic] and
  31. [link ref_BOOST_TEST_CASE_TEMPLATE manual] registration interface.
  32. [tip The test case template facility is preferable to the approach in example above, since execution of each sub test
  33. case is guarded and counted separately. It produces a better test log/results report (in example above in case of
  34. 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
  35. the sub test case.]
  36. [#ref_BOOST_AUTO_TEST_CASE_TEMPLATE][h4 Template test case with automated registration]
  37. A template test case, registered automatically and in place of its implementation, is declared through the macro
  38. __BOOST_AUTO_TEST_CASE_TEMPLATE__:
  39. ``
  40. BOOST_AUTO_TEST_CASE_TEMPLATE(test_case_name, formal_type_parameter_name, collection_of_types);
  41. ``
  42. The arguments are as follow:
  43. # `test_case_name`: the test case template name: unique test cases template identifier
  44. # `formal_type_parameter_name`: the name of a formal template parameter:
  45. name of the type the test case template is instantiated with
  46. # `collection_of_types`: the collection of types to instantiate test case template with.
  47. This is an *arbitrary MPL sequence* or a sequence of types wrapped in a `std::tuple`
  48. (since [link ref_CHANGE_LOG_3_7 __UTF__ v3.7], if supported by the compiler)
  49. The resulting name of the test is a composition of the `test_case_name` parameter and the current
  50. type being tested. Since [link ref_CHANGE_LOG_3_12 __UTF__ v3.12], the framework tries to unify
  51. the name of the resulting type across various platforms such that they are easier to reference
  52. from the [link boost_test.runtime_config.test_unit_filtering command line filter].
  53. [bt_example example10..Test case template with automated registration..run-fail]
  54. [warning Since [link ref_CHANGE_LOG_3_7 __UTF__ v3.7], the __UTF__ does not allow for duplicate test case name
  55. under the same test suite. As test names are derived from the types in the `collection_of_types`,
  56. this indirectly means that *having a duplicate type* in the
  57. `collection_of_types` *yields an error*.]
  58. [note If you prefer having the template parameter list directly in the declaration of __BOOST_AUTO_TEST_CASE_TEMPLATE__,
  59. you may use the macro [@www.boost.org/doc/libs/release/libs/utility/identity_type/doc/html/index.html `BOOST_IDENTITY_TYPE`].
  60. The previous example gives (note the double parenthesis around the MPL list):
  61. ``
  62. #include <boost/utility/identity_type.hpp>
  63. BOOST_AUTO_TEST_CASE_TEMPLATE(
  64. my_test,
  65. T,
  66. BOOST_IDENTITY_TYPE((boost::mpl::list<
  67. int,
  68. long,
  69. unsigned char
  70. >)) )
  71. {
  72. BOOST_TEST( sizeof(T) == (unsigned)4 );
  73. }
  74. ``
  75. ]
  76. [#ref_BOOST_TEST_CASE_TEMPLATE][h4 Test case template with manual registration]
  77. To manually register template test cases, two macros should be used:
  78. * __BOOST_TEST_CASE_TEMPLATE_FUNCTION__ to define the template test case body
  79. * __BOOST_TEST_CASE_TEMPLATE__ to register the test case based on the previous declaration
  80. The macro __BOOST_TEST_CASE_TEMPLATE_FUNCTION__ requires two arguments:
  81. # the name of the test case template and
  82. # the name of the format type parameter
  83. ``
  84. BOOST_TEST_CASE_TEMPLATE_FUNCTION(test_case_name, type_name);
  85. ``
  86. ``
  87. BOOST_TEST_CASE_TEMPLATE_FUNCTION( test_case_name, type_name )
  88. {
  89. // test case template body
  90. }
  91. ``
  92. The macro __BOOST_TEST_CASE_TEMPLATE_FUNCTION__ is intended to be used in place of nullary function template
  93. signature:
  94. ``
  95. template <typename type_name>
  96. void test_case_name()
  97. {
  98. // test case template body
  99. }
  100. ``
  101. The only difference is that the __BOOST_TEST_CASE_TEMPLATE_FUNCTION__ makes the test case template name usable in
  102. the template argument list.
  103. __BOOST_TEST_CASE_TEMPLATE__ requires two arguments:
  104. # the name of the test case template and
  105. # Boost.MPL compatible collection of types to instantiate it with.
  106. The names passed to both macros should be the same.
  107. ``
  108. BOOST_TEST_CASE_TEMPLATE(test_case_name, collection_of_types);
  109. ``
  110. [bt_example example09..Manually registered test case template..run-fail]
  111. __BOOST_TEST_CASE_TEMPLATE__ creates an instance of the test case generator. When passed to the method [memberref
  112. boost::unit_test::test_suite::add `test_suite::add`], the generator produces a separate sub test case for each type in
  113. the supplied collection of types and registers it immediately in the test suite. Each test case is based on the test
  114. case template body instantiated with a particular test type.
  115. The names for the ['sub test cases] are deduced from the macro argument `test_case_name`. If you prefer to assign
  116. different test case names, you need to use the underlying [headerref boost/test/tree/test_unit.hpp `make_test_case`] interface instead.
  117. Both test cases creation and registration is performed in the test module initialization function.
  118. [warning Since [link ref_CHANGE_LOG_3_7 __UTF__ v3.7], the __UTF__ does not allow for duplicate test case name
  119. under the same test suite. As test names are derived from the types in the `collection_of_types`,
  120. this indirectly means that having a duplicate of types in the
  121. `collection_of_types` will yield an error.]
  122. [endsect] [/template test cases]
  123. [/EOF]