文档章节

C++单元测试:boost.test

加壹
 加壹
发布于 2014/04/28 16:16
字数 1051
阅读 2011
收藏 1

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

参考

  1. b2 Invocation
  2. Getting Started on Windows
  3. Getting Started on Unix Variants

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

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

链接

  1. C++ Compilers: Microsoft Visual C++
  2. 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
}

官方的例子,很简单:

  1. "BOOST_TEST_MODULE",定义测试模块。之后再include "unit_test.hpp"。
  2. "BOOST_AUTO_TEST_CASE",自动注册测试用例。
  3. 测试工具分为"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 */
  1. 上述定义了两个"TEST_SUITE":test_case1、test_case1在test_suite1内;test_case3、test_case4在test_suite2内。
  2. 注意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
};

然后,使用时:

  1. "BOOST_FIXTURE_TEST_CASE",用在测试用例上。
  2. "BOOST_FIXTURE_TEST_SUITE",用在测试套件上。这样的话,测试套件每个测试用例就不用写了。
  3. "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()
  1. 输出会有四组"setup fixture"与"teardown fixture",每个用到的测试用例下各自一份。
  2. "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上配置时用到了。

© 著作权归作者所有

加壹
粉丝 25
博文 21
码字总数 20538
作品 0
无锡
私信 提问
ReSharper C++ 2016.1 发布

ReSharper C++ 2016.1 发布了,本次发布ReSharper C++增加了许多新功能,以及对现有功能的改进。主要如下: 支持Boost.Test。 增强了单元测试功能,ReSharper会检测单个刺激试验以及测试套件...

oschina
2016/05/20
4.5K
9
ReSharper Ultimate 2016.1.1 发布

ReSharper Ultimate 2016.1.1 发布了。ReSharper是一款由jetbrains开发的针对C#, VB.NET, ASP.NET, XML, 和 XAML的编辑器。沿袭了jetbrains开发工具一贯的优良传统,ReSharper拥有高度智能的...

oschina
2016/05/05
2.3K
10
CLion 2017.3.1 EAP 发布,包含 bug 修复

CLion 2017.3.1 的 Early Access Preview 版本发布了,这是对最近发布的主要 CLion 更新的 bug 修复更新。 更新内容: 生成操作中的模板在CLion 2017.3生成定义开始使用函数模板。使用此更新...

周其
2017/12/14
618
1
计划6月12号后到深圳,求个深圳的C++或Python工作

本人,25岁,2011年本科数学专业毕业。本科是985,211。在校成绩3.61/4 (5/58)。拿过国家奖学金。 工作经验: 接近两年: 刚毕业到毕业后一年,给老师打工,做科研助理,主要是OpenGL,和简单...

crackhoppe
2013/05/23
1K
12
玩转Google开源C++单元测试框架Google Test系列(gtest)(总)

前段时间学习和了解了下Google的开源C++单元测试框架Google Test,简称gtest,非常的不错。 我们原来使用的是自己实现的一套单元测试框架,在使用过程中,发现越来越多使用不便之处,而这样不...

元谷
2013/12/18
332
0

没有更多内容

加载失败,请刷新页面

加载更多

消息中间件——RabbitMQ的高级特性

前言 前面我们介绍了RabbitMQ的安装、各大消息中间件的对比、AMQP核心概念、管控台的使用、快速入门RabbitMQ。本章将介绍RabbitMQ的高级特性。分两篇(上/下)进行介绍。 消息如何保障100%的...

Java架构师ya七
36分钟前
6
0
如何编写高质量的 JS 函数(1) -- 敲山震虎篇

本文首发于 vivo互联网技术 微信公众号 链接:https://mp.weixin.qq.com/s/7lCK9cHmunvYlbm7Xi7JxQ 作者:杨昆 一千个读者,有一千个哈姆雷特。 此系列文章将会从函数的执行机制、鲁棒性、函...

vivo互联网技术
今天
6
0
学会这5个Excel技巧,让你拒绝加班

在网上,随处都可以看到Excel技巧,估计已看腻了吧?但下面5个Excel技巧会让你相见恨晚。关键的是它们个个还很实用 图一 技巧1:快速删除边框 有时当我们处理数据需要去掉边框,按Ctrl+Shif...

干货趣分享
今天
11
0
JS基础-该如何理解原型、原型链?

JS的原型、原型链一直是比较难理解的内容,不少初学者甚至有一定经验的老鸟都不一定能完全说清楚,更多的"很可能"是一知半解,而这部分内容又是JS的核心内容,想要技术进阶的话肯定不能对这个...

OBKoro1
今天
10
0
高防CDN的出现是为了解决网站的哪些问题?

高防CDN是为了更好的服务网络而出现的,是通过高防DNS来实现的。高防CDN是通过智能化的系统判断来路,再反馈给用户,可以减轻用户使用过程的复杂程度。通过智能DNS解析,能让网站访问者连接到...

云漫网络Ruan
今天
17
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部