Boost:Test
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
: 예외처리. -
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()
이후 LDFLAGS
에 -lboost_unit_test_framework
를 추가하고 컴파일 한다.
test/included
included
아래의 헤더를 사용하면 main이 포함되어 있어, 별도로 boost_unit_test_framework
를 링크할 필요가 없다.
하지만 위와 같이 하면 빌드가 더 오래 걸리니 아래와 같이 컴파일 하자.
Hoe to use
boost/test/test_tools.hpp
를 참조하면 된다.
-
#define BOOST_TEST_DYN_LINK
:boost_unit_test_framework
를 동적으로 링크하기 위해 Define 해야 한다. -
#define BOOST_TEST_MODULE test
: 테스트 모듈 이름. -
BOOST_AUTO_TEST_CASE(test_case_name) { /* test body */ }
: 자동으로 추가되는 테스트 define. -
BOOST_AUTO_TEST_SUITE(vtest_basic);
~BOOST_AUTO_TEST_SUITE_END()
: 테스트 스위트 OPEN ~ END. 테스트케이스를 묶을 수 있다. 또한 if문과 같이 중첩도 가능하다. -
BOOST_CHECK(true);
: Assert와 동일. -
BOOST_CHECK_EQUAL(1, 1);
: 두 인자의 동등함을 비교한다. -
BOOST_TEST_CHECKPOINT("before divzero"); i=100/0;
: 시그널이나 트랩등이 걸린 경우 마지막 체크 포인트를 찍어준다. -
BOOST_TEST_MESSAGE("message");
: 상세 메시지를 출력한다. 단 일반적으로 출력되지 않고 명령행 인자로--log_level=all
를 넘겨야 한다. 또는 환경변수에BOOST_TEST_LOG_LEVEL=all
를 설정해도 된다. (boost.test의 parameters 참조)
class test
클래스를 사용한 좀 복잡한 테스트 스위트는 아래와 같다.
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()
참고로 아래와 같은 방식으로도 가능하다.
#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
MinGW에서 아래와 같은 에러 메시지가 출력될 수 있다.
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() ) );
이 경우 #include
앞에 아래와 같이 추가하면 된다.
#ifdef __MINGW32__
// Mingw doesn't define putenv() needed by Boost.Test
extern int putenv(char*);
#endif
multiple cpp files
여러 개의 소스파일에 유닛 테스트를 분리하고 싶을 경우 아래와 같이 하면 된다.
우선 첫 번째 소스 파일에 모듈명을 추가하여 테스트 케이스를 추가한다.
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE vtest_unit_test
#include <boost/test/unit_test.hpp>
// TODO: Insert test case.
그리고 두 번째 이후의 소스 파일은 모듈을을 추가하지 말고 오직 헤더만 추가한다.