]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/test/doc/test_organization/fixtures.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / test / doc / test_organization / fixtures.qbk
CommitLineData
7c673cae
FG
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
8[section:fixtures Fixtures]
9In general terms a test fixture or test context is the collection of one or more of the following items, required
10to perform the test:
11
12* preconditions
13* particular states of tested units
14* necessary cleanup procedures
15
16Though these tasks are encountered in many if not all test cases, what makes a test fixture different is
17repetition. Where a normal test case implementation does all preparatory and cleanup work itself, a test fixture
18allows it to be implemented in a separate reusable unit.
19
20With introduction of e[*X]treme [*P]rogramming (XP), the testing style, that require test setup/cleanup repetition,
21has become even more popular. Single XP adopted test modules may contain hundreds of single assertion test cases,
22many requiring very similar test setup/cleanup. This is the problem that the test fixture is designed to solve.
23
24In practice a test fixture usually is a combination of `setup` and `teardown` functions, associated with test case.
25The former serves the purposes of test setup. The later is dedicated to the cleanup tasks. Ideally we'd like for a
26test module author to be able to define variables used in fixtures on the stack and, at the same time, to refer to
27them directly in a test case.
28
29It's important to understand that C++ provides a way to implement a straightforward test fixture solution
30that almost satisfies our requirements without any extra support from the test framework. Here is how simple test
31module with such a fixture may look like:
32
33``
34struct MyFixture {
35 MyFixture() { i = new int; *i = 0 }
36 ~MyFixture() { delete i; }
37
38 int* i;
39};
40
41__BOOST_AUTO_TEST_CASE__( test_case1 )
42{
43 MyFixture f;
44 // do something involving f.i
45}
46
47__BOOST_AUTO_TEST_CASE__( test_case2 )
48{
49 MyFixture f;
50 // do something involving f.i
51}
52``
53
54
55This is a generic solution that can be used to implement any kind of shared setup or cleanup procedure. Still
56there are several more or less minor practical issues with this pure C++ based fixtures solution:
57
58* We need to add a fixture declaration statement into each test case manually.
59* Objects defined in fixture are references with `<fixture-instance-name>` prefix.
60* There is no place to execute a ['global] fixture, which performs ['global] setup/cleanup
61 procedures before and after testing.
62
63The __UTF__ lets you define a fixture according to [link boost_test.tests_organization.fixtures.models several generic interfaces],
64and thus helps you with following tasks:
65
66* define shared setup/teardown procedures for a single or group of test cases
67* define setup/teardown procedures which are performed once per test suite
68* define global setup/teardown procedures which are performed once per test module
69
70[/ ###################################################################################### ]
71[section:models Fixture models]
72
73Several fixture interfaces are supported by the __UTF__. The choice of the interface depends
74mainly on the usage of the fixture.
75
76[h3 Fixture class model]
77The __UTF__ defines the generic fixture class model as follows:
78
79``
80struct <fixture-name>{
81 <fixture-name>(); // setup function
82 ~<fixture-name>(); // teardown function
83};
84``
85
86In other words a fixture is expected to be implemented as a class where the class constructor serves as a `setup`
87method and class destructor serves as `teardown` method. The __UTF__ opted to avoid explicit names in fixture
88interface for `setup` and `teardown` methods, since it is considered most natural in C++ for tasks similar to RAII and
89coincides with the pure C++ solution discussed above.
90
91This model is expected from fixtures used with __BOOST_FIXTURE_TEST_CASE__ and __BOOST_FIXTURE_TEST_SUITE__.
92
93[caution The above interface prevents you from reporting errors in the `teardown` procedure using an exception. It does make
94 sense though: if somehow more than one fixture is assigned to a test unit (e.g. using __decorator_fixture__ decorator),
95 you want all `teardown` procedures to run, even if some may experience problems.
96]
97
98
99[h3 Flexible models]
100In addition to __BOOST_FIXTURE_TEST_CASE__ and __BOOST_FIXTURE_TEST_SUITE__ the __UTF__ allows to associate fixture with
101test unit using the decorator __decorator_fixture__. This decorator supports additional models for declaring
102the `setup` and `teardown`:
103
104* a fixture defined according to the fixture class model above
105* a fixture defined according to the extended fixture class model, which allows for the fixture constructor to
106 takes one argument. For example:
107
108 struct Fx
109 {
110 std::string s;
111 Fx(std::string s = "") : s(s)
112 { BOOST_TEST_MESSAGE("set up " << s); }
113 ~Fx() { BOOST_TEST_MESSAGE("tear down " << s); }
114 };
115
116* a fixture defined as a pair of free functions for the `setup` and `teardown` (latter optional)
117
118 void setup() { BOOST_TEST_MESSAGE("set up"); }
119 void teardown() { BOOST_TEST_MESSAGE("tear down"); }
120
121For complete example of test module which uses these models please check decorator __decorator_fixture__.
122
123[endsect] [/section generic fixture]
124
125
126
127[/ ###################################################################################### ]
128[section:case Test case fixture]
129A /test case fixture/ is a fixture consumed by a test case: the fixture `setup` is called before the test case executes,
130and the fixture `teardown` is called after the test case finished its execution, independently from its execution state.
131
132The __UTF__ provides several ways of defining fixtures for test-cases, each of which having their properties:
133
134* the declaration of a fixture for a single test case, letting the test case access the members of the fixture,
135* the declaration of one or more fixture(s) for a single test case, without accessing the members and with a flexible interface,
136* the declaration of a fixture for a group of test-cases defined by a subtree, with access to the members of the fixture.
137
138
139[h3 Single test case fixture]
140The following two methods are available for declaring a fixture attached to one particular test case:
141
142* the use of the macro __BOOST_FIXTURE_TEST_CASE__ in place of __BOOST_AUTO_TEST_CASE__, which let access to the members of the fixture
143* the use of the decorator __decorator_fixture__, which does not let access to the members but enables
144 the definition of several fixtures for one test case.
145
146[/ ------------------------------------------------------------------------ ]
147[#test_case_fixture_macro][h4 Fixture with `BOOST_FIXTURE_TEST_CASE`]
148
149`BOOST_FIXTURE_TEST_CASE` serves as a test case declaration with a fixture, and is meant be used in place of
150the test case declaration with __BOOST_AUTO_TEST_CASE__:
151
152``
153 BOOST_FIXTURE_TEST_CASE(test_case_name, fixture_name);
154``
155
156The only difference from the macro __BOOST_AUTO_TEST_CASE__ is the presence of an extra argument `fixture_name`.
157The public and protected members of the fixture are directly accessible from the test case body. Only
158one fixture can be attached to a test-case [footnote it is still possible to define a class inheriting from several
159fixtures, that will act as a proxy fixture.].
160
161[note You can't access private members of fixture, but then why would you make anything private?]
162
163[bt_example example18..Per test case fixture..run-fail]
164
165In this example only `test_case1` and `test_case2` have fixture `F` assigned.
166You still need to refer to the fixture name in every test case. [link test_case_fixture_subtree This] section
167explains how a same fixture can be declared for a subtree under a test suite.
168
169[/ ------------------------------------------------------------------------ ]
170[#test_case_fixture_decorator][h4 Fixture with `fixture` decorator]
171By using the decorator __decorator_fixture__, it is possible to:
172
173* attach several fixtures to a unique test case
174* use a flexible fixture interface (see [link boost_test.tests_organization.fixtures.models here])
175
176[note Using the decorator approach, it is not possible to access the members of the fixture (in case the fixture is implemented
177 as a class)]
178
179
180
181[/ ###################################################################################### ]
182[#test_case_fixture_subtree][h3 Fixture for a complete subtree]
183
184If all test cases in a test sub tree require the same fixture (you can group test cases in a test suite based on a
185fixture required) you can make another step toward an automation of a test fixture assignment. To assign the
186same shared fixture for all test cases in a test suite, use the macro __BOOST_FIXTURE_TEST_SUITE__ in place of the
187macro __BOOST_AUTO_TEST_SUITE__ for automated test suite creation and registration.
188
189``
190 BOOST_FIXTURE_TEST_SUITE(suite_name, fixture_name);
191``
192
193Once again the only difference from the macro __BOOST_AUTO_TEST_SUITE__ usage is the presence of
194an extra argument - the fixture name. And now, you not only have direct access to the public and protected members
195of the fixture, but also do not need to refer to the fixture name in test case definition. All test cases assigned
196the same fixture automatically.
197
198[tip If necessary you can reset the fixture for a particular test case using the macro
199 __BOOST_FIXTURE_TEST_CASE__. Similarly you can reset the fixture for a particular sub
200 test suite using __BOOST_FIXTURE_TEST_SUITE__.
201]
202
203[note The fixture assignment is ['deep]. In other words unless reset by another
204 __BOOST_FIXTURE_TEST_SUITE__ or __BOOST_FIXTURE_TEST_CASE__ definition the
205 same fixture is assigned to all test cases of a test suite, including ones that belong to the sub test suites.
206]
207
208[bt_example fixture_02..Test suite level fixture..run]
209
210[caution The fixture constructor and destructor is called for each test cases (the state of the
211 fixture is not shared among the test cases).]
212
213
214
215[endsect] [/ per test case]
216
217[/ ###################################################################################### ]
218[section:per_test_suite_fixture Test suite entry/exit fixture]
219
220It is possible to define a test suite entry/exit fixture, so that the `setup` function is called only once upon entering
221the test suite, prior to running any of its test cases; and similarly the `teardown` function is also called only once
222upon the test suite exit, after all the enclosed test cases have been run. This is facilitated by the
223/decorator/ __decorator_fixture__.
224
225[bt_example fixture_03..Test suite entry/exit fixture..run]
226
227In case of this fixture type, however, it is not possible to access any members of the fixture object.
228
229[caution This is not equivalent to using the method described [link test_case_fixture_subtree here].]
230
231[endsect] [/ per_test_suite_fixture]
232
233[/ ###################################################################################### ]
234[section:global Global fixture]
235
236Any global initialization that needs to be performed every time testing begins or a global cleanup that is to be
237performed once testing is finished is called a global fixture. The __UTF__ global fixture design is based on the
238[link boost_test.tests_organization.fixtures.models generic test class fixture model]. The global
239fixture design allows any number of global fixtures to be defined in any test file that constitutes a test module.
240Though some initialization can be implemented in the test module initialization function, there are several
241reasons to prefer the global fixture approach:
242
243* There is no place for cleanup/`teardown` operations in the initialization function.
244* Unlike the initialization function, the global fixture `setup` method invocation is guarded by the execution
245 monitor. That means that all uncaught errors that occur during initialization are properly reported.
246* Any number of different global fixtures can be defined, which allows you to split initialization code by
247 category.
248* The fixture allows you to place matching `setup`/`teardown` code in close vicinity in your test module code.
249* If the whole test tree is constructed automatically the initialization function is empty and auto-generated by
250 the __UTF__. To introduce the initialization function can be more work than the use of a global fixture facility,
251 while global fixture is more to the point.
252* Since all fixtures follow the same generic model you can easily switch from local per test case fixtures to
253 the global one.
254* If you are using the interactive test runner (non-supplied yet) global test fixtures are applied to every run,
255 while an initialization function is executed only once during a test module startup (just make sure that
256 it's what you really want).
257
258To define a global test module fixture you need to implement a class that matched generic fixture model and
259passed it as an argument to the macro __BOOST_GLOBAL_FIXTURE__.
260
261``
262 BOOST_GLOBAL_FIXTURE(fixture_name);
263``
264
265The statement, that performs global fixture definition, has to reside at a test file scope.
266
267[bt_example example20..Global fixture..run]
268
269[endsect] [/section Global fixtures]
270
271[endsect] [/ section fixtures]
272
273[/EOF]