mirror of https://gitee.com/bigwinds/arangodb
167 lines
5.4 KiB
Plaintext
167 lines
5.4 KiB
Plaintext
[/
|
|
/ Copyright (c) 2015 Boost.Test contributors
|
|
/
|
|
/ 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)
|
|
/]
|
|
|
|
[section:contexts Contexts]
|
|
|
|
Contexts are a facility provided by the __UTF__ in order to be able to trace the location of assertions better. To grasp
|
|
the idea, consider the following example:
|
|
|
|
|
|
``
|
|
void test_operations(Processor& processor, int limit)
|
|
{
|
|
for (int i = 0; i < limit; ++i) {
|
|
BOOST_TEST(processor.op1(i));
|
|
for (int j = 0; j < i; ++j) {
|
|
BOOST_TEST(processor.op2(i, j));
|
|
}
|
|
}
|
|
}
|
|
``
|
|
|
|
In case of failure, in order to see in the logs at which point of the loops the failure occurred, we need some extra
|
|
information in the assertion:
|
|
|
|
|
|
``
|
|
BOOST_TEST(processor.op1(i));
|
|
``
|
|
|
|
replaced by
|
|
|
|
``
|
|
BOOST_TEST_MESSAGE(processor.op1(i), "With parameter i = " << i);
|
|
``
|
|
|
|
We see in this trivial example that a context, which is the variable `i` in this case, should be acknowledged by the
|
|
assertion `BOOST_CHECK` in a particular way. In the approach above, this is done by adding a message to the assertion
|
|
itself.
|
|
|
|
What if the context is more complex than that? In case the complexity of the context increases, the fact that the
|
|
assertion and the context is tightly coupled as in the approach above is difficult to maintain:
|
|
|
|
``
|
|
void test_operations(Processor& processor, int limit, int level)
|
|
{
|
|
for (int i = 0; i < limit; ++i) {
|
|
BOOST_TEST_MESSAGE(processor.op1(i),
|
|
"With optimization level " << level << ", With parameter i = " << i);
|
|
for (int j = 0; j < i; ++j) {
|
|
BOOST_TEST_MESSAGE(processor.op2(i, j),
|
|
"With optimization level " << level <<
|
|
", With parameter i = " << i << ", With parameter j = " << j);
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(test1)
|
|
{
|
|
Processor processor;
|
|
|
|
for (int level = 0; level < 3; ++level) {
|
|
processor.optimization_level(level);
|
|
test_operations(processor, 2, level);
|
|
}
|
|
}
|
|
``
|
|
|
|
Note the length of the messages, the repetition, and the fact, that we pass argument `level` to function
|
|
`test_operations` only for the sake of generating an error message in case of a failure.
|
|
|
|
Therefore, *loose* coupling between the context of an assertion and the assertion point is a property that is desirable.
|
|
|
|
[#ref_BOOST_TEST_INFO][h3 Assertion-bound context]
|
|
|
|
Macro `BOOST_TEST_INFO` can be used to define an error message to be bound to the first following assertion. If (and only
|
|
if) the assertion fails, the bound message will be displayed along:
|
|
|
|
[bt_example example80_contexts..Assertion-bound context..run-fail]
|
|
|
|
Observe the following things. The information composed inside `BOOST_TEST_INFO` is bound only to the first assertion
|
|
following the declaration. Thus bound information is only displayed if the assertion fails; otherwise the message is
|
|
discarded. The `BOOST_TEST_INFO` declaration does not have to immediately precede the assertion, it is allowed to
|
|
intertwine them with other instructions, they can even be declared in different scopes. Therefore it is also possible to
|
|
bind more than one information to a given assertion.
|
|
|
|
With `BOOST_TEST_INFO`, we can improve our initial example as follows:
|
|
|
|
|
|
``
|
|
void test_operations(Processor& processor, int limit, int level)
|
|
{
|
|
for (int i = 0; i < limit; ++i) {
|
|
BOOST_TEST_INFO("With optimization level " << level);
|
|
BOOST_TEST_INFO("With parameter i = " << i);
|
|
BOOST_TEST(processor.op1(i));
|
|
for (int j = 0; j < i; ++j) {
|
|
BOOST_TEST_INFO("With optimization level " << level);
|
|
BOOST_TEST_INFO("With parameter i = " << i);
|
|
BOOST_TEST_INFO("With parameter j = " << j);
|
|
BOOST_TEST(processor.op2(i, j));
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(test1)
|
|
{
|
|
Processor processor;
|
|
|
|
for (int level = 0; level < 3; ++level) {
|
|
processor.optimization_level(level);
|
|
test_operations(processor, 2, level);
|
|
}
|
|
}
|
|
``
|
|
|
|
[#ref_BOOST_TEST_CONTEXT][h3 Scope-bound context]
|
|
|
|
Macro `BOOST_TEST_CONTEXT` defines a diagnostic message and a scope. The message is bound to every assertion in the scope,
|
|
and is displayed along with every failed assertion.
|
|
|
|
[bt_example example81_contexts..Scope-bound context..run-fail]
|
|
|
|
Observe the following things. After the `BOOST_TEST_CONTEXT` macro we have a pair of braces: they define the scope in which
|
|
the diagnostic message is in effect. If there is no braces, the scope applies only to the following statement.
|
|
`BOOST_TEST_CONTEXT` declarations can nest.
|
|
|
|
With `BOOST_TEST_CONTEXT`, we can further improve our initial example, by putting variable `level` into a scope-level context
|
|
and not pass it as function parameter:
|
|
|
|
``
|
|
void test_operations(Processor& processor, int limit)
|
|
{
|
|
for (int i = 0; i < limit; ++i) {
|
|
BOOST_TEST_INFO("With parameter i = " << i);
|
|
BOOST_TEST(processor.op1(i));
|
|
for (int j = 0; j < i; ++j) {
|
|
BOOST_TEST_INFO("With parameter i = " << i);
|
|
BOOST_TEST_INFO("With parameter j = " << j);
|
|
BOOST_TEST(processor.op2(i, j));
|
|
}
|
|
}
|
|
}
|
|
|
|
BOOST_AUTO_TEST_CASE(test1)
|
|
{
|
|
Processor processor;
|
|
|
|
for (int level = 0; level < 3; ++level) {
|
|
BOOST_TEST_CONTEXT("With optimization level " << level) {
|
|
processor.optimization_level(level);
|
|
test_operations(processor, 2);
|
|
}
|
|
}
|
|
}
|
|
``
|
|
If we observe that variable `i` also applies in a certain scope, we can improve our example further still.
|
|
|
|
[bt_example example82_contexts..Using contexts..run-fail]
|
|
|
|
[endsect] [/ contexts ]
|
|
|
|
|