diff --git a/doc/examples/example70_decorators.cpp b/doc/examples/decorator_01.cpp similarity index 54% rename from doc/examples/example70_decorators.cpp rename to doc/examples/decorator_01.cpp index 287f3b9d..c6f35c3c 100644 --- a/doc/examples/example70_decorators.cpp +++ b/doc/examples/decorator_01.cpp @@ -6,25 +6,20 @@ // See http://www.boost.org/libs/test for the library home page. //[example_code -#define BOOST_TEST_MODULE example70 -#include +#define BOOST_TEST_MODULE decorator_01 +#include namespace utf = boost::unit_test; -BOOST_TEST_DECORATOR( - + utf::label("trivial") -) -BOOST_AUTO_TEST_CASE( test_case1 ) +BOOST_AUTO_TEST_CASE(test_case1, *utf::label("trivial")) { BOOST_TEST(true); } -BOOST_TEST_DECORATOR( - + utf::label("trivial") - + utf::label("cmp") - + utf::description("testing equality of ones") -) -BOOST_AUTO_TEST_CASE( test_case2 ) +BOOST_AUTO_TEST_CASE(test_case2, + * utf::label("trivial") + * utf::label("cmp") + * utf::description("testing equality of ones")) { BOOST_TEST(1 == 1); } -//] +//] \ No newline at end of file diff --git a/doc/examples/example70_decorators.output b/doc/examples/decorator_01.output similarity index 64% rename from doc/examples/example70_decorators.output rename to doc/examples/decorator_01.output index 40a84279..92bed6ca 100644 --- a/doc/examples/example70_decorators.output +++ b/doc/examples/decorator_01.output @@ -1,11 +1,11 @@ //[example_output -> example70 --run_test=@trivial +> decorator_01 --run_test=@trivial Running 2 test cases... *** No errors detected -> example70 --run_test=@cmp +> decorator_01 --run_test=@cmp Running 1 test case... *** No errors detected diff --git a/doc/examples/example71_decorators.cpp b/doc/examples/decorator_02.cpp similarity index 64% rename from doc/examples/example71_decorators.cpp rename to doc/examples/decorator_02.cpp index af911f84..cde476fb 100644 --- a/doc/examples/example71_decorators.cpp +++ b/doc/examples/decorator_02.cpp @@ -6,24 +6,21 @@ // See http://www.boost.org/libs/test for the library home page. //[example_code -#define BOOST_TEST_MODULE example71 -#include +#define BOOST_TEST_MODULE decorator_02 +#include namespace utf = boost::unit_test; -BOOST_TEST_DECORATOR( - + utf::label("trivial") -) -BOOST_AUTO_TEST_SUITE( suite1 ) +BOOST_AUTO_TEST_SUITE(suite1, *utf::label("trivial")) - BOOST_AUTO_TEST_CASE( test_case1 ) + BOOST_AUTO_TEST_CASE(test_case1) { BOOST_TEST(true); } - BOOST_AUTO_TEST_CASE( test_case2 ) + BOOST_AUTO_TEST_CASE(test_case2) { BOOST_TEST(1 == 1); } BOOST_AUTO_TEST_SUITE_END() -//] +//] \ No newline at end of file diff --git a/doc/examples/example72_decorators.output b/doc/examples/decorator_02.output similarity index 66% rename from doc/examples/example72_decorators.output rename to doc/examples/decorator_02.output index 5eacccec..2d7c7bc6 100644 --- a/doc/examples/example72_decorators.output +++ b/doc/examples/decorator_02.output @@ -1,5 +1,5 @@ //[example_output -> example72 --run_test=@trivial +> decorator_02 --run_test=@trivial Running 2 test cases... *** No errors detected diff --git a/doc/examples/example72_decorators.cpp b/doc/examples/decorator_03.cpp similarity index 50% rename from doc/examples/example72_decorators.cpp rename to doc/examples/decorator_03.cpp index 24e6fa00..ce824992 100644 --- a/doc/examples/example72_decorators.cpp +++ b/doc/examples/decorator_03.cpp @@ -6,28 +6,34 @@ // See http://www.boost.org/libs/test for the library home page. //[example_code -#define BOOST_TEST_MODULE example72 -#include +#define BOOST_TEST_MODULE decorator_03 +#include namespace utf = boost::unit_test; -BOOST_AUTO_TEST_SUITE( suite1 ) +BOOST_AUTO_TEST_SUITE(suite1, *utf::label("trivial")) - BOOST_AUTO_TEST_CASE( test_case1 ) + BOOST_AUTO_TEST_CASE(test_case1) { BOOST_TEST(true); } BOOST_AUTO_TEST_SUITE_END() -BOOST_TEST_DECORATOR( - + utf::label("trivial") -) -BOOST_AUTO_TEST_SUITE( suite1 ) +BOOST_AUTO_TEST_SUITE(suite1, *utf::label("simple")) - BOOST_AUTO_TEST_CASE( test_case2 ) + BOOST_AUTO_TEST_CASE(test_case2) { - BOOST_TEST(1 == 1); + BOOST_TEST(true); } BOOST_AUTO_TEST_SUITE_END() -//] + +BOOST_AUTO_TEST_SUITE(suite1) + + BOOST_AUTO_TEST_CASE(test_case3) + { + BOOST_TEST(true); + } + +BOOST_AUTO_TEST_SUITE_END() +//] \ No newline at end of file diff --git a/doc/examples/decorator_03.output b/doc/examples/decorator_03.output new file mode 100644 index 00000000..175b3446 --- /dev/null +++ b/doc/examples/decorator_03.output @@ -0,0 +1,12 @@ +//[example_output +> decorator_03 --run_test=@trivial +Running 3 test cases... + +*** No errors detected + + +> decorator_03 --run_test=@simple +Running 3 test cases... + +*** No errors detected +//] \ No newline at end of file diff --git a/doc/examples/example71_decorators.output b/doc/examples/example71_decorators.output deleted file mode 100644 index 192cf7b9..00000000 --- a/doc/examples/example71_decorators.output +++ /dev/null @@ -1,6 +0,0 @@ -//[example_output -> example71 --run_test=@trivial -Running 2 test cases... - -*** No errors detected -//] \ No newline at end of file diff --git a/doc/examples/example73_decorators.cpp b/doc/examples/example73_decorators.cpp deleted file mode 100644 index 5c1e4241..00000000 --- a/doc/examples/example73_decorators.cpp +++ /dev/null @@ -1,36 +0,0 @@ -// (C) Copyright Andrzej Krzemienski 2015. -// Distributed under the Boost Software License, Version 1.0. -// (See accompanying file LICENSE_1_0.txt or copy at -// http://www.boost.org/LICENSE_1_0.txt) - -// See http://www.boost.org/libs/test for the library home page. - -//[example_code -#define BOOST_TEST_MODULE example73 -#include -namespace utf = boost::unit_test; - -BOOST_TEST_DECORATOR( - + utf::label("trivial") -) -BOOST_AUTO_TEST_SUITE( suite1 ) - - BOOST_AUTO_TEST_CASE( test_case1 ) - { - BOOST_TEST(true); - } - -BOOST_AUTO_TEST_SUITE_END() - -BOOST_TEST_DECORATOR( - + utf::label("simple") -) -BOOST_AUTO_TEST_SUITE( suite1 ) - - BOOST_AUTO_TEST_CASE( test_case2 ) - { - BOOST_TEST(1 == 1); - } - -BOOST_AUTO_TEST_SUITE_END() -//] diff --git a/doc/examples/example73_decorators.output b/doc/examples/example73_decorators.output deleted file mode 100644 index f62b892f..00000000 --- a/doc/examples/example73_decorators.output +++ /dev/null @@ -1,10 +0,0 @@ -//[example_output -> example73 --run_test=@trivial -Test setup error: no test cases matching filter - - -> example73 --run_test=@simple -Running 2 test cases... - -*** No errors detected -//] \ No newline at end of file diff --git a/doc/test_organization/decorators.qbk b/doc/test_organization/decorators.qbk index a80b9ade..51d18430 100644 --- a/doc/test_organization/decorators.qbk +++ b/doc/test_organization/decorators.qbk @@ -7,35 +7,102 @@ [#ref_BOOST_TEST_DECORATOR][section:decorators Decorators] -Decorators provide a way to configure certain aspects of an automatically registered test unit. +Decorators is a mechanism for attaching various pieces of information to test units in a uniform manner. These pieces of information affect how the test tree is processed during the execution of the program. They range from test unit descriptions to floating-point tolerance or the number of expected failures. They are listed in detail in the following sections. -[bt_example example70_decorators..Test unit decorators] +A list of decorators can be associated with a given test case by providing the second argument to macro __BOOST_AUTO_TEST_CASE__ or the third argument to macro __BOOST_FIXTURE_TEST_CASE__. Similarly, a list of decorators can be associated with a given test suite by providing the second argument to macro __BOOST_AUTO_TEST_SUITE__ or the third argument to macro __BOOST_FIXTURE_TEST_SUITE__. + +[bt_example decorator_01..Test unit decorators] + +Each decorator in the list is preceded by an asterisk (`*`); the subsequent syntax resembles a function call and is specified in detail for each decorator. If there is more than one decorator in the list, they are concatenated with no additional separator; each asterisk indicates the beginning of a decorator. In the above example, test case `test_case1` has one associated ['decorator:] __decorator_label__. This means that when test units are executed selectively by label, this test case will match to label `"trivial"`. Test case `test_case2` has three associated decorators: two of type `label` and one of type `description`. -Test case `test_case1` has one associated ['decorator:] `label`. This means that when test units are executed selectively by label, this test case will match to label "trivial". Test case `test_case2` has three associated decorators: two of type `label` and one of type `description`. [h3 Suite-level decorators] -It is also possible to decorate test suites. +Similarly, it is possible to apply decorators to test suites. -[bt_example example71_decorators..Test suite decorators] +[bt_example decorator_02..Test suite decorators] -The meaning of such decoration is that it applies to every test unit inside the suite. In the case above both test cases `suite1/test_case1` and `suite1/test_case2` have tag "trivial". +How a decorator associated with a test suite affects the processing of the test units inside varies with the decorator and is described for each decorator in subsequent sections. The meaning of the above example is that when tests are run selectively by label, every test unit in suite `suite1` will be run. -A decorator applies to every test unit in the suite, even if the scope of a given suite is opened twice: +It is possible to open a test suite scope more than once in a a translation unit; or to open the same test suite scope in multiple translation unit. If this is the case, the total decorator list associated with the test suite is the union of decorators specified for each test suite scope opening. This can be illustrated with an example. -[bt_example example72_decorators..Decorators on multiple suite openings] +[bt_example decorator_03..Decorators on multiple suite openings] -In the above case, both test cases `suite1.test_case1` and `suite1/test_case2` have tag "trivial". +In the above example, the scope of test suite `suite1` is opened three times. This results in a test suite containing three test cases and associated with two __decorator_label__ decorators. Therefore running tests by label `"trivial"` as well as by label `"simple"` both result in executing all three test cases from the suite. -In case the scope of the suite is opened twice in the same file with different decorator sets, the last decorator set is in effect: -[bt_example example73_decorators..Different decorators on multiple suite openings] +[h3 Compatibility with older compilers] -In the above case, both test cases `suite1/test_case1` and `suite1/test_case2` have tag "simple". Tag "trivial" has been overwritten. +The syntax for decorators requires that the compiler supports variadic macros (added in C++11). If you intend for your test program to compile also on compilers without variadic macros, it is recommended that you use the portable syntax. This syntax is summarized in the following table: -In case the scope of the suite is opened twice in two different translation units with different decorator sets, it is unspecified which of the two sets is in effect. This mechanism is tied to the order of initialization of global objects. +[table + [[Preferred syntax][Compatible syntax]] + [[``` +// test case registration + +BOOST_AUTO_TEST_CASE(test_case, *decor1() *decor2()) +{ + // assertions +} + ```][``` +BOOST_TEST_DECORATOR(*decor1() *decor2()) +BOOST_AUTO_TEST_CASE(test_case) +{ + // assertions +} + ```]] + + [[``` +// test case with fixture registration + +BOOST_FIXTURE_TEST_CASE(test_case, Fx, *decor1() *decor2()) +{ + // assertions +} + ```][``` +BOOST_TEST_DECORATOR(*decor1() *decor2()) +BOOST_FIXTURE_TEST_CASE(test_case, Fx) +{ + // assertions +} + ```]] + + [[``` +// test suite registration + +BOOST_AUTO_TEST_SUITE(test_suite, *decor1() *decor2()) -[tip It is therefore recommended that you either make sure that each time the test suite scope is opened, it has the same decorator set, or you identify a ['privileged] opening of the suite and decorate only it, while keeping all the other openings undecorated.] + // test units + +BOOST_AUTO_TEST_SUITE_END() + ```][``` +BOOST_TEST_DECORATOR(*decor1() *decor2()) +BOOST_AUTO_TEST_SUITE(test_suite) + + // test units + +BOOST_AUTO_TEST_SUITE_END() + ```]] + +[[``` +// test suite with fixture registration + +BOOST_FIXTURE_TEST_SUITE(test_suite, Fx, *decor1() *decor2()) + + // test units + +BOOST_AUTO_TEST_SUITE_END() + ```][``` +BOOST_TEST_DECORATOR(*decor1() *decor2()) +BOOST_FIXTURE_TEST_SUITE(test_suite, Fx) + + // test units + +BOOST_AUTO_TEST_SUITE_END() + ```]] +] + +Throughout the reminder of this documentation we use only the preferred syntax. [/=================================================================] diff --git a/include/boost/test/unit_test_suite.hpp b/include/boost/test/unit_test_suite.hpp index 12ca0a45..7698015c 100644 --- a/include/boost/test/unit_test_suite.hpp +++ b/include/boost/test/unit_test_suite.hpp @@ -82,7 +82,7 @@ BOOST_AUTO_TU_REGISTRAR( suite_name )( \ // ************************************************************************** // #define BOOST_FIXTURE_TEST_SUITE_WITH_DECOR(suite_name, F, decorators) \ - BOOST_FIXTURE_TEST_SUITE_WITH_DECOR( suite_name, decorators ) \ + BOOST_AUTO_TEST_SUITE_WITH_DECOR( suite_name, decorators ) \ typedef F BOOST_AUTO_TEST_CASE_FIXTURE; \ /**/