]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [/ |
2 | / Copyright (c) 2015 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:contexts Contexts] | |
9 | ||
10 | Contexts are a facility provided by the __UTF__ in order to be able to trace the location of assertions better. To grasp | |
11 | the idea, consider the following example: | |
12 | ||
13 | ||
14 | `` | |
15 | void test_operations(Processor& processor, int limit) | |
16 | { | |
17 | for (int i = 0; i < limit; ++i) { | |
18 | BOOST_TEST(processor.op1(i)); | |
19 | for (int j = 0; j < i; ++j) { | |
20 | BOOST_TEST(processor.op2(i, j)); | |
21 | } | |
22 | } | |
23 | } | |
24 | `` | |
25 | ||
26 | In case of failure, in order to see in the logs at which point of the loops the failure occurred, we need some extra | |
27 | information in the assertion: | |
28 | ||
29 | ||
30 | `` | |
31 | BOOST_TEST(processor.op1(i)); | |
32 | `` | |
33 | ||
34 | replaced by | |
35 | ||
36 | `` | |
37 | BOOST_TEST_MESSAGE(processor.op1(i), "With parameter i = " << i); | |
38 | `` | |
39 | ||
40 | We see in this trivial example that a context, which is the variable `i` in this case, should be acknowledged by the | |
41 | assertion `BOOST_CHECK` in a particular way. In the approach above, this is done by adding a message to the assertion | |
42 | itself. | |
43 | ||
44 | What if the context is more complex than that? In case the complexity of the context increases, the fact that the | |
45 | assertion and the context is tightly coupled as in the approach above is difficult to maintain: | |
46 | ||
47 | `` | |
48 | void test_operations(Processor& processor, int limit, int level) | |
49 | { | |
50 | for (int i = 0; i < limit; ++i) { | |
51 | BOOST_TEST_MESSAGE(processor.op1(i), | |
52 | "With optimization level " << level << ", With parameter i = " << i); | |
53 | for (int j = 0; j < i; ++j) { | |
54 | BOOST_TEST_MESSAGE(processor.op2(i, j), | |
55 | "With optimization level " << level << | |
56 | ", With parameter i = " << i << ", With parameter j = " << j); | |
57 | } | |
58 | } | |
59 | } | |
60 | ||
61 | BOOST_AUTO_TEST_CASE(test1) | |
62 | { | |
63 | Processor processor; | |
64 | ||
65 | for (int level = 0; level < 3; ++level) { | |
66 | processor.optimization_level(level); | |
67 | test_operations(processor, 2, level); | |
68 | } | |
69 | } | |
70 | `` | |
71 | ||
72 | Note the length of the messages, the repetition, and the fact, that we pass argument `level` to function | |
73 | `test_operations` only for the sake of generating an error message in case of a failure. | |
74 | ||
75 | Therefore, *loose* coupling between the context of an assertion and the assertion point is a property that is desirable. | |
76 | ||
77 | [#ref_BOOST_TEST_INFO][h3 Assertion-bound context] | |
78 | ||
79 | Macro `BOOST_TEST_INFO` can be used to define an error message to be bound to the first following assertion. If (and only | |
80 | if) the assertion fails, the bound message will be displayed along: | |
81 | ||
82 | [bt_example example80_contexts..Assertion-bound context..run-fail] | |
83 | ||
84 | Observe the following things. The information composed inside `BOOST_TEST_INFO` is bound only to the first assertion | |
85 | following the declaration. Thus bound information is only displayed if the assertion fails; otherwise the message is | |
86 | discarded. The `BOOST_TEST_INFO` declaration does not have to immediately precede the assertion, it is allowed to | |
87 | intertwine them with other instructions, they can even be declared in different scopes. Therefore it is also possible to | |
88 | bind more than one information to a given assertion. | |
89 | ||
90 | With `BOOST_TEST_INFO`, we can improve our initial example as follows: | |
91 | ||
92 | ||
93 | `` | |
94 | void test_operations(Processor& processor, int limit, int level) | |
95 | { | |
96 | for (int i = 0; i < limit; ++i) { | |
97 | BOOST_TEST_INFO("With optimization level " << level); | |
98 | BOOST_TEST_INFO("With parameter i = " << i); | |
99 | BOOST_TEST(processor.op1(i)); | |
100 | for (int j = 0; j < i; ++j) { | |
101 | BOOST_TEST_INFO("With optimization level " << level); | |
102 | BOOST_TEST_INFO("With parameter i = " << i); | |
103 | BOOST_TEST_INFO("With parameter j = " << j); | |
104 | BOOST_TEST(processor.op2(i, j)); | |
105 | } | |
106 | } | |
107 | } | |
108 | ||
109 | BOOST_AUTO_TEST_CASE(test1) | |
110 | { | |
111 | Processor processor; | |
112 | ||
113 | for (int level = 0; level < 3; ++level) { | |
114 | processor.optimization_level(level); | |
115 | test_operations(processor, 2, level); | |
116 | } | |
117 | } | |
118 | `` | |
119 | ||
120 | [#ref_BOOST_TEST_CONTEXT][h3 Scope-bound context] | |
121 | ||
122 | Macro `BOOST_TEST_CONTEXT` defines a diagnostic message and a scope. The message is bound to every assertion in the scope, | |
123 | and is displayed along with every failed assertion. | |
124 | ||
125 | [bt_example example81_contexts..Scope-bound context..run-fail] | |
126 | ||
127 | Observe the following things. After the `BOOST_TEST_CONTEXT` macro we have a pair of braces: they define the scope in which | |
128 | the diagnostic message is in effect. If there is no braces, the scope applies only to the following statement. | |
129 | `BOOST_TEST_CONTEXT` declarations can nest. | |
130 | ||
131 | With `BOOST_TEST_CONTEXT`, we can further improve our initial example, by putting variable `level` into a scope-level context | |
132 | and not pass it as function parameter: | |
133 | ||
134 | `` | |
135 | void test_operations(Processor& processor, int limit) | |
136 | { | |
137 | for (int i = 0; i < limit; ++i) { | |
138 | BOOST_TEST_INFO("With parameter i = " << i); | |
139 | BOOST_TEST(processor.op1(i)); | |
140 | for (int j = 0; j < i; ++j) { | |
141 | BOOST_TEST_INFO("With parameter i = " << i); | |
142 | BOOST_TEST_INFO("With parameter j = " << j); | |
143 | BOOST_TEST(processor.op2(i, j)); | |
144 | } | |
145 | } | |
146 | } | |
147 | ||
148 | BOOST_AUTO_TEST_CASE(test1) | |
149 | { | |
150 | Processor processor; | |
151 | ||
152 | for (int level = 0; level < 3; ++level) { | |
153 | BOOST_TEST_CONTEXT("With optimization level " << level) { | |
154 | processor.optimization_level(level); | |
155 | test_operations(processor, 2); | |
156 | } | |
157 | } | |
158 | } | |
159 | `` | |
160 | If we observe that variable `i` also applies in a certain scope, we can improve our example further still. | |
161 | ||
162 | [bt_example example82_contexts..Using contexts..run-fail] | |
163 | ||
164 | [endsect] [/ contexts ] | |
165 | ||
166 |