2
0
mirror of https://github.com/boostorg/test.git synced 2026-02-19 14:52:09 +00:00
Files
test/doc/testing_tools/boost_test_universal_macro.qbk
Gennadiy Rozental e80d648e9c super =
2015-05-23 00:07:30 -04:00

117 lines
6.1 KiB
Plaintext

[/
/ Copyright (c) 2015 Raffi Enficiaud
/
/ 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:boost_test_universal_macro BOOST_TEST: universal and general purpose assertions]
Once a test case has been declared, the body of this test should be written. A test case is a
sequence of operations in which *assertions* are inserted. Those assertions evaluate /statements/ that verify the integrity
of the pre and post conditions of the operations. There are three kind of assertions, having different meaning on the
consistency of the test case:
* *requirements*: this is a strong condition for the operations following the assertion to be valid.
This type of assertions should be used when a pre-condition for the test is not met or when the test-case cannot continue.
If such as assertion fails, the test case execution stops immediately, and the test-case is flagged as /failed/.
* *checks*: this is the most commonly used assertion level. If the statement evaluates to `false`, the test case is
flagged as failed but its execution continues.
* *warnings*: this is an assertion providing information. The test case execution continues and a warning message is logged.
The warning does not change the success status of a test case.
These three levels of assertions are reported into the test log and output, as described in details in the
[link boost_test.testing_tools.tools_assertion_severity_level severity levels] section. The granularity of the
report depends on the current [link boost_test.utf_reference.rt_param_reference.log_level log level] and
[link boost_test.utf_reference.rt_param_reference.report_level report level].
A unique interface is given by three variants of the `BOOST_TEST` assertion:
* `BOOST_TEST_REQUIRE`
* `BOOST_TEST_CHECK` or just `BOOST_TEST`
* `BOOST_TEST_WARN`
As their name suggests these assertions are, in order, for /requirement/, /checks/ and /warnings/.
[warning To get all the functionalities of `BOOST_TEST` family of assertions, a C++11 capable compiler is required, especially
supporting the `auto` and `decltype` keywords and the variadic macros. The documentation focuses on these set of compilers. A
limited support is provided for C++03 compilers.]
[/ ################################################ ]
[section:floating_point Floating point comparison]
Unless you specify otherwise, when two floating-point types are compared inside assertion __BOOST_TEST__,
the resulting check is not 'direct' (as implemented by operators `==` and `<` for these types),
but uses [link boost_test.testing_tools.extended_comparison.testing_floating_points comparison with tolerance] instead.
The tolerance threshold used is the one defined per test case. See
the decorator __decorator_tolerance__ for setting test-case-local tolerance.
If there is a need for customizing floating point comparison tolerance per single assertion, you can do it by providing a
second argument to __BOOST_TEST__. Such second argument is called a /manipulator/.
[caution The support for manipulators requires that your compiler supports variadic macros, `auto` for type deduction
and `decltype`. These are C++11 features, but are also available on some pre-C++11 compilers.]
Manipulator [funcref boost::test_tools::tolerance] can be used in three ways. They are illustrated in the following example:
[bt_example test_float_01..manipulator tolerance]
In the above example, the first assertion is using the default tolerance, which makes the comparison fail. In the second assertion
a tolerance for type `double` of value 0.002 is specified. The numbers are compared using the algorithm Equ (4) on
[link boost_test.testing_tools.extended_comparison.testing_floating_points this page]; the algorithm treats the two values as
sufficiently small to pass the test. In the third assertion we use the percent tolerance; it is equivalent to the second
assertion. The fourth assertion is another syntax for representing the percent tolerance: it is equivalent to the third assertion.
[note All floating point comparisons use Equ (4) on [link boost_test.testing_tools.extended_comparison.testing_floating_points this page].]
Manipulator `tolerance` specifies the tolerance only for a single floating-point type. This type is deduced from form
the numeric value passed along the manipulator:
[table
[[manipulator expression][semantics]]
[[`tolerance(0.5)`][relative tolerance for type `double` changed to 0.5]]
[[`tolerance(float(0.5))`][relative tolerance for type `float` changed to 0.5]]
[[`tolerance(0.5f)`][relative tolerance for type `float` changed to 0.5]]
[[`5.0 % tolerance()`][relative tolerance for type `double` changed to 0.05 (5.0 * 0.01)]]
[[`5.0f % tolerance()`][relative tolerance for type `float` changed to 0.05]]
]
In case different types of floating point numbers are being compared in one assertion, the types are promoted according
to C++ type promotion and conversion rules, and the resulting type is the one whose tolerance is considered. For instance,
when setting a tolerance for mixed `float`-to-`double` comparison, the tolerance for type `double` needs to be set. This
is illustrated by the following example.
[bt_example test_float_02..tolerance for mixed floating-point types]
The specified tolerance only applies when comparing values that are recognized as floating point types in the expression
tree contained in the assertion body. It does not apply to user-defined types even when they use floating-point comparison inside:
[bt_example test_float_03..tolerance for non-fp types]
The __UTF__ recognizes that a given type `T` is a floating-point type using the expression
[classref boost::math::fpc::tolerance_based]`<T>::value`. This meta-function already returns true for built-in
floating-point types as well as for user defined-types that specialize `std::numeric_limits`. You can also specialize
[classref boost::math::fpc::tolerance_based] for your type directly:
[bt_example test_float_04..adapting user-defined types for tolerance-based comparison]
[endsect] [/ floating points]
[endsect] [/ boost_test_universal_macro]