Boost:Test
lastmod 2015-04-09created 2015-03-1716 edits
Test Tools
The UTF's supplies a toolbox of testing tools to ease creation and maintenance of test programs and provide a uniform error reporting mechanism. The toolbox supplied in most part in a form of macro and function declarations. While the functions can be called directly, the usual way to use testing tools is via convenience macros. All macros arguments are calculated once, so it's safe to pass complex expressions in their place. All tools automatically supply an error location: a file name and a line number. The testing tools are intended for unit test code rather than library or production code, where throwing exceptions, using assert(), boost::concept_check or BOOST_STATIC_ASSERT() may be more suitable ways to detect and report errors. For list of all supplied testing tools and usage examples see the reference.
Testing tools flavors
All the tools are supplied in three flavors(levels): WARN, CHECK and REQUIRE. For example: BOOST_WARN_EQUAL, BOOST_CHECK_EQUAL, BOOST_REQUIRE_EQUAL. If an assertion designated by the tool passes, confirmation message can be printed in log output. If an assertion designated by the tool failed, depending on the level following will happened:
| Level | Test log content | Errors counter | Test execution |
| WARN | warning in <test case name>: condition <assertion description> is not satisfied | not affected | continues |
| CHECK | error in <test case name>: test <assertion description> failed | increased | continues |
| REQUIRE | fatal error in <test case name>: critical test <assertion description> failed | increased | aborts |
Reference
-
BOOST_CHECK_THROW: Exception handling. -
BOOST_<level> -
BOOST_<level>_BITWISE_EQUAL -
BOOST_<level>_CLOSE -
BOOST_<level>_CLOSE_FRACTION -
BOOST_<level>_EQUAL -
BOOST_<level>_EQUAL_COLLECTION -
BOOST_<level>_EXCEPTION -
BOOST_<level>_GE -
BOOST_<level>_GT -
BOOST_<level>_LE -
BOOST_<level>_LT -
BOOST_<level>_MESSAGE -
BOOST_<level>_NE -
BOOST_<level>_NO_THROW -
BOOST_<level>_PREDICATE -
BOOST_<level>_SMALL -
BOOST_<level>_THROW -
BOOST_ERROR -
BOOST_FAIL -
BOOST_IS_DEFINED
Sample test code
#ifdef __MINGW32__
// Mingw doesn't define putenv() needed by Boost.Test
extern int putenv(char*);
#endif
#define BOOST_TEST_MODULE enumtest
#include <boost/test/included/unit_test.hpp>
BOOST_AUTO_TEST_SUITE(enumtest)
BOOST_AUTO_TEST_CASE(test1)
{
BOOST_CHECK(false);
}
BOOST_AUTO_TEST_SUITE_END()
Then add -lboost_unit_test_framework to LDFLAGS and compile.
test/included
The headers under included contain main, so there is no need to link boost_unit_test_framework separately.
However, doing it this way makes the build take longer, so compile as follows instead.
Hoe to use
Refer to boost/test/test_tools.hpp.
-
#define BOOST_TEST_DYN_LINK: Must be defined to linkboost_unit_test_frameworkdynamically. -
#define BOOST_TEST_MODULE test: Test module name. -
BOOST_AUTO_TEST_CASE(test_case_name) { /* test body */ }: Defines a test that is registered automatically. -
BOOST_AUTO_TEST_SUITE(vtest_basic);~BOOST_AUTO_TEST_SUITE_END(): Test suite OPEN ~ END. Groups test cases together. Suites can also be nested, like if statements. -
BOOST_CHECK(true);: Same as Assert. -
BOOST_CHECK_EQUAL(1, 1);: Compares the two arguments for equality. -
BOOST_TEST_CHECKPOINT("before divzero"); i=100/0;: Marks the last checkpoint when a signal or trap occurs. -
BOOST_TEST_MESSAGE("message");: Prints a detailed message. However, it is not printed by default; you must pass--log_level=allas a command-line argument. Alternatively, you can setBOOST_TEST_LOG_LEVEL=allas an environment variable. (See the parameters of boost.test)
class test
A somewhat more complex test suite using a class is as follows.
BOOST_AUTO_TEST_SUITE(suite2)
struct adder {
adder() { BOOST_TEST_MESSAGE("setup fixture"); }
~adder() { BOOST_TEST_MESSAGE("teardown fixture"); }
int add(int x, int y) { return x+y; }
};
BOOST_FIXTURE_TEST_CASE(test_adder_1, adder)
{
// adder 의 non-private 멤버에 바로 접근이 가능
BOOST_CHECK_EQUAL(add(1,1),1);
}
BOOST_AUTO_TEST_SUITE_END()
For reference, the following approach also works.
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE Fixtures
#include <boost/test/unit_test.hpp>
struct Massive
{
int m;
Massive() : m(2)
{
BOOST_TEST_MESSAGE("setup mass");
}
~Massive()
{
BOOST_TEST_MESSAGE("teardown mass");
}
};
BOOST_FIXTURE_TEST_SUITE(Physics, Massive)
BOOST_AUTO_TEST_CASE(specialTheory)
{
int e = 32;
int c = 4;
BOOST_CHECK(e == m * c * c);
}
BOOST_AUTO_TEST_CASE(newton2)
{
int f = 10;
int a = 5;
BOOST_CHECK(f == m * a);
}
Exception test
#define BOOST_TEST_MAIN
#include <boost/test/unit_test.hpp>
class my_exception{};
BOOST_AUTO_TEST_CASE( test )
{
int i = 0;
BOOST_CHECK_THROW( i++, my_exception );
}
Troubleshooting
error: putenv not declared
On MinGW, the following error message may be printed.
C:/boost/boost_1_55_0/boost/test/utils/runtime/config.hpp:95:51: error: 'putenv'
was not declared in this scope
putenv( const_cast<char*>( fs.str().c_str() ) );
In this case, add the following before #include.
#ifdef __MINGW32__
// Mingw doesn't define putenv() needed by Boost.Test
extern int putenv(char*);
#endif
multiple cpp files
To split unit tests across multiple source files, do the following.
First, add the module name in the first source file and add test cases.
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE vtest_unit_test
#include <boost/test/unit_test.hpp>
// TODO: Insert test case.
Then, in the second and later source files, do not add the module; include only the header.
Favorite site
- Boost Test Library: Unit Test Framework
- The UTF compilation variants and procedures
- Minimal usage of the boost test framework
- C++ Unit Testing With Boost.Test
- Open source C/C++ unit testing tools, Part 1: Get to know the Boost unit test framework