您的位置:首页 > 编程语言 > C语言/C++

C++单元测试:boost.test

2016-04-30 13:51 495 查看
C++单元测试:boost.test

1) 准备


1.1) 编译boost test

cd boost_1_55_0

# On Windows
bootstrap.bat
b2 --toolset=msvc-10.0 --build-type=minimal --with-test runtime-link=static stage
# 1) --toolset=msvc-10.0: 指定编译器,这儿是VS2010。其他版本可见链接1。
# 2) --build-type=minimal: 默认,按其描述相当于设定了下述属性:
#   link=static runtime-link=shared threading=multi variant=debug,release
# 3) --with-test: 指定编译test。一旦用了'--with',就只编译指定库了。
# 4) runtime-link=static: 添加静态链接运行时库。link与runtime-link区分,可见链接2。
# 5) stage: 只编译和安装库文件,也就是不会包含头文件。

# On Linux
# 是否已预安装
ll /usr/lib/libboost*
# yum list installed boost*
./bootstrap.sh
./b2 --toolset=gcc --build-type=minimal --with-test stage
# 1) --prefix: 安装路径,默认/usr/local。
# 2) --build-type=minimal: 默认,Linux下相当于设定了下述属性:
#   link=static,shared threading=multi variant=release

# 帮助
./b2 --help
./b2 --show-libraries


参考

b2 Invocation
Getting
Started on Windows
Getting
Started on Unix Variants

中文的话,可参考这两篇:

Boost下载安装编译配置使用指南
VS2010 编译安装boost库

链接

C++
Compilers: Microsoft Visual C++
link和runtime-link,搭配shared和static


1.2) 引入boost test

# On Windows,静态链接方式
"IncludePath" += boost_1_55_0
"LibraryPath" += boost_1_55_0\stage\lib
指定选项:/EHa,/MT[d]

# On Linux,动态链接方式
定义宏:BOOST_TEST_DYN_LINK
链接时:-lboost_unit_test_framework


2) 使用

官方文档Boost Test Library讲的很详细。主要是几下几方面:


2.1) Hello the testing
world

test_hello.cc
#define BOOST_TEST_MODULE MyTest
#include <boost/test/unit_test.hpp>

int add( int i, int j ) { return i+j; }

BOOST_AUTO_TEST_CASE( my_test )
{
// seven ways to detect and report the same error:
BOOST_CHECK( add( 2,2 ) == 4 );        // #1 continues on error

BOOST_REQUIRE( add( 2,2 ) == 4 );      // #2 throws on error

if( add( 2,2 ) != 4 )
BOOST_ERROR( "Ouch..." );            // #3 continues on error

if( add( 2,2 ) != 4 )
BOOST_FAIL( "Ouch..." );             // #4 throws on error

if( add( 2,2 ) != 4 ) throw "Ouch..."; // #5 throws on error

BOOST_CHECK_MESSAGE( add( 2,2 ) == 4,  // #6 continues on error
"add(..) result: " << add( 2,2 ) );

BOOST_CHECK_EQUAL( add( 2,2 ), 4 );   // #7 continues on error
}


官方的例子,很简单:

“BOOST_TEST_MODULE”,定义测试模块。之后再include “unit_test.hpp”。
“BOOST_AUTO_TEST_CASE”,自动注册测试用例。
测试工具分为"WARN”,“CHECK"和"REQUIRE"三个等级。“CHECK"与"REQUIRE"差别为:前者即使失败,也仍然继续;后者则认为是必须的,为严重错误,直接退出当前测试。

测试工具参考,见testing tools reference


2.2) 自动注册测试套件(Test
suites)

用以下宏把"TEST_CASE"包起来即成:
BOOST_AUTO_TEST_SUITE(test_suite_name)
BOOST_AUTO_TEST_SUITE_END()


test_suite.cc
#define BOOST_TEST_MODULE MySuiteTest
#include <boost/test/included/unit_test.hpp>

/* test_suite1 start */
BOOST_AUTO_TEST_SUITE( test_suite1 )
// test_case1 in test_suite1
BOOST_AUTO_TEST_CASE( test_case1 )
{
BOOST_WARN( sizeof(int) < 4 );
}
// test_case2 in test_suite1
BOOST_AUTO_TEST_CASE( test_case2 )
{
BOOST_REQUIRE_EQUAL( 1, 2 );  // note: REQUIRE
BOOST_FAIL( "Should never reach this line" );
}
BOOST_AUTO_TEST_SUITE_END()
/* test_suite1 end */

/* test_suite2 start */
BOOST_AUTO_TEST_SUITE( test_suite2 )
// test_case3 in test_suite2
BOOST_AUTO_TEST_CASE( test_case3 )
{
BOOST_CHECK( true );
}
BOOST_AUTO_TEST_SUITE_END()
/* test_suite2 end */

// test_case_on_file_scope
BOOST_AUTO_TEST_CASE( test_case_on_file_scope )
{
BOOST_CHECK( true );
}

/* test_suite2 start */
BOOST_AUTO_TEST_SUITE( test_suite2 )
// test_case4 in test_suite2
BOOST_AUTO_TEST_CASE( test_case4 )
{
BOOST_CHECK( false );
}
BOOST_AUTO_TEST_SUITE_END()
/* test_suite2 end */


上述定义了两个"TEST_SUITE”:test_case1、test_case1在test_suite1内;test_case3、test_case4在test_suite2内。
注意test_case_on_file_scope,其上下分别是test_suite2的test_case3、test_case4。也就是测试套件可以分为多个部分,以便放在不同文件。


2.3) 使用测试夹具(Test fixtures

重复的测试数据,都可以放到一个夹具里。其模板如下:
struct <fixture-name>{
<fixture-name>(); // setup function
~<fixture-name>(); // teardown function
};


然后,使用时:

“BOOST_FIXTURE_TEST_CASE”,用在测试用例上。
“BOOST_FIXTURE_TEST_SUITE”,用在测试套件上。这样的话,测试套件每个测试用例就不用写了。
“BOOST_GLOBAL_FIXTURE”,用在全局上。

test_suite.cc
#define BOOST_TEST_MODULE MyFixtureTest
#include <boost/test/included/unit_test.hpp>
#include <iostream>

/* 3) Global fixture */
struct MyConfig {
MyConfig() : g_i( 0 )
{
instance() = this;
std::cout << "global setup\n";
}
~MyConfig()
{
std::cout << "g_i: " << g_i << std::endl;
std::cout << "global teardown\n";
}
static MyConfig *&instance();
int g_i;
};
BOOST_GLOBAL_FIXTURE(MyConfig);

MyConfig *&MyConfig::instance()
{
static MyConfig *s_inst = 0;
return s_inst;
}

/* 1) Per test case fixture */
struct F {
F() : i( 0 ) { std::cout << "setup fixture\n"; }
~F()         { std::cout << "teardown fixture\n"; }
int i;
};
BOOST_FIXTURE_TEST_CASE( test_case1, F )
{
BOOST_CHECK( i == 1 );  // failed: i == 0
++i;
}
BOOST_FIXTURE_TEST_CASE( test_case2, F )
{
BOOST_CHECK_EQUAL( i, 0 );  // pass: i == 0
++(MyConfig::instance()->g_i);
}
BOOST_AUTO_TEST_CASE( test_case3 )
{
BOOST_CHECK( true );
std::cout << "g_i: " << MyConfig::instance()->g_i << std::endl;
}

/* 2) Test suite level fixture */
BOOST_FIXTURE_TEST_SUITE( test_suite1, F )
BOOST_AUTO_TEST_CASE( test_case1 )
{
BOOST_CHECK( i == 1 );  // failed: i == 0
++i;
}
BOOST_AUTO_TEST_CASE( test_case2 )
{
BOOST_CHECK_EQUAL( i, 0 );  // pass: i == 0
++(MyConfig::instance()->g_i);
}
BOOST_AUTO_TEST_SUITE_END()


输出会有四组"setup fixture"与"teardown fixture”,每个用到的测试用例下各自一份。
“global setup"与"global teardown"则分别于头尾,只有一个实例。官方文档没看到如何访问其成员,这里用了单例方式来处理。

3) 总结

本文主要介绍了boost单元测试框架的使用。

附1:样例工程btest_start

下载:btest_start.zip

目录树如下:
btest_start/
├─build/
│  ├─btest_start-gcc.cbp   # for gnu gcc
│  └─btest_start-msvc.cbp  # for msvc 2010
├─src/
├─third_party/
│  └─boost_1_55_0/
└─tools/


C::B工程,boost_1_55_0/目录Windows上配置时用到了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: