boost 单元测试

原文:http://www.jianshu.com/p/9a87918023fb

基本概念

Boost test库提供了一个用于单元测试的基于命令行界面的测试套件UTF:Unit Test Framework,具有单元测试、检测内存泄露、监控程序运行的功能。

测试模块

  1. 测试安装
  2. 测试主体:测试主体是测试的模块的实际运行部分,由测试用例测试套件组成的测试树形成
  3. 测试清理
  4. 测试运行器
测试用例

测试用例是一个包含多个测试断言的函数;是可以被独立执行测试的最小单元。

测试套件

测试套件是测试用例的容器,可以嵌套,包含一个或多个测试用例,将多个测试用例分组管理,共享安装、清理代码。

测试夹具(test fixture)

测试安装和测试清理好比c++中的构造函数和析构函数,“测试夹具”实现了自动的测试安装和测试清理。

超轻量及测试lightweight_test

在头文件<boost/detail/lightweight_test.hpp>中定义,他提供三个最简单的测试断言

BOOST_TEST      //相当于BOOST_CHECK,断言表达式成立
BOOST_ERROR     //直接断言失败,输出一条错误信息
BOOST_TEST_EQ   //相当于BOOST_CHECK_EQUAL,断言两个表达式相等

Boost最小化测试套件 minimal test

boost提供的最简单的测试套件,有基本的测试断言,适合简单测试

该套件在头文件中

#include <boost/test/minimal.hpp>

定义,使用时只包含这个头文件就可以了,不需要链接其他的库,非常方便。在这个头文件中已经定义了一个mian()函数,我们不需要在写main()函数了,只需要实现一个test_main(int argc, char *argv[])就可以了。这个头文件中定义了四个断言宏,可以供我们使用。

BOOST_CHECK(predicate)      //断言表达式通过,如不通过不影响程序继续执行
BOOST_REQUIRE(predicate)    //断言表达式必须通过,如不通过程序终止
BOOST_ERROR(message)        // 给出一个错误信息,程序继续执行
BOOST_FAIL(message)         // 给出一个错误信息,程序终止执行

下面是一个小栗子:

#include "boost/test/minimal.hpp"
#include "boost/format.hpp"
#include "iostream"

int test_main(int argc, char *argv[])             // 测试主函数,不需要在定义main()
{
    using namespace boost;
    format fmt("%d-%d");

    BOOST_CHECK(fmt.size() == 0);                 // 验证fmt对象初始化,不通过继续执行

    fmt % 12 % 34;

    BOOST_REQUIRE(fmt.str() == "12-34");         // 验证结果,不通过则不予执行

    BOOST_ERROR("演示一条错误信息");                 // 打印一条错误信息,继续执行

    fmt.clear();
    fmt % 12;
    try {
        std::cout << fmt;
    }
    catch (...) {
        BOOST_FAIL("致命错误,测试终止");             // 给出一个错误信息,终止执行
    }

    return 0;
}

程序输出:

boost_test.cpp(9): test fmt.size() == 0 failed in function: 'int test_main(int, char **)'
boost_test.cpp(12): 演示一条错误信息 in function: 'int test_main(int, char **)'
boost_test.cpp(20): 致命错误,测试终止 in function: 'int test_main(int, char **)'

总结,minimal test方便简单,但功能有限,适用于单元测试的演示,或者较小的程序段。

UTF测试断言

UTF中的测试断言:BOOST_LEVEL_ITEM

LEVELWARN警告级,不增加错误数量,不影响程序运行
 CHECK检查级别,增加错误数量,不影响程序运行
 REQUIRE最高级别,增加错误数量,程序终止运行
ITEMEQUAL/CLOSE测试相等性
 GE/GT/LT/LE/NE测试不等性
 (NO_)THROW是否抛出异常
 MESSAGE测试信息
 ......

组合出来就是如

BOOST_CHECK_EQUAL(l, r)
BOOST_REQUIRE_GE(l, r)

测试实例

举个栗子:

#define BOOST_TEST_MAIN
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#include <boost/smart_ptr.hpp>
using namespace boost;

// 开始测试套件s_smart_ptr
BOOST_AUTO_TEST_SUITE(s_smart_ptr)

// 测试用例1:t_scoped_ptr
BOOST_AUTO_TEST_CASE(t_scoped_ptr)
{
    scoped_ptr<int> p(new int(874));
    BOOST_CHECK(p);                     // 测试指针p的可用性
    BOOST_CHECK_EQUAL(*p, 875);         // 测试p解引用的值

    p.reset();
    BOOST_CHECK(p == 0);                // 测试p为空
}

// 测试用例2:t_shared_ptr
BOOST_AUTO_TEST_CASE(t_shared_ptr)
{
    shared_ptr<int> p(new int(100));

    BOOST_CHECK(p);
    BOOST_CHECK_EQUAL(*p, 100);
    BOOST_CHECK_EQUAL(p.use_count(), 1);
    shared_ptr<int> p2 = p;
    BOOST_CHECK_EQUAL(p, p2);
    BOOST_CHECK_EQUAL(p2.use_count(), 2);

    *p2 = 255;
    BOOST_CHECK_EQUAL(*p, 255);
    BOOST_CHECK_GT(*p, 200);
}

// 结束测试套件
BOOST_AUTO_TEST_SUITE_END()

关于#define BOOST_TEST_DYN_LINK,如果不加的话会出现下面的错误:

Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

编译时同时需要链接-lboost_unit_test_framework

测试夹具

前面说测试夹具就好比c++的构造函数和析构函数,也可以理解为在执行测试之前设置一个环境,在测试完成时清除它。

看两个栗子吧:

#define BOOST_TEST_MODULE example
#include <boost/test/included/unit_test.hpp>
#include <iostream>

struct F {
    F():i(0) { std::cout << "setup" << std::endl; }
    ~F() { std::cout << "teardown" << std::endl; }

    int i;
};

BOOST_AUTO_TEST_SUITE( test )

BOOST_FIXTURE_TEST_CASE( test_case1, F ) {
    BOOST_CHECK( i == 1 );
    ++i;
}

BOOST_AUTO_TEST_CASE( test_case2 ) {
    BOOST_REQUIRE( 2 > 1 );
}

BOOST_AUTO_TEST_CASE( test_case3 ) {
    int i = 1;
    BOOST_CHECK_EQUAL( i, 1 );
    ++i;
}

BOOST_AUTO_TEST_SUITE_END()

输出结果是:

Running 3 test cases...
setup
boost_test.cpp:22: error in "test_case1": check i == 1 failed
teardown

*** 1 failure detected in test suite "Master Test Suite"

另一个栗子:

#define BOOST_TEST_MAIN
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>
#include <boost/assign.hpp>
#include <vector>
using namespace std;
using namespace boost;

// 全局测试夹具类
struct global_fixture {
    global_fixture() {cout << "global setup" << endl;}
    ~global_fixture() {cout << "global teardown" << endl;}
};

// 定义全局夹具
BOOST_GLOBAL_FIXTURE(global_fixture);

// 测试套件夹具类
struct assign_fixture {
    assign_fixture() {cout << "suit setup" << endl;}
    ~assign_fixture() {cout << "suit teardown" << endl;}

    std::vector<int> v;
};

// 定义测试套件级别的夹具
BOOST_FIXTURE_TEST_SUITE(s_assign, assign_fixture)

BOOST_AUTO_TEST_CASE(t_assign1) {
    using namespace boost::assign;
    v += 1, 2, 3, 4;
    BOOST_CHECK_EQUAL(v.size(), 4);
    BOOST_CHECK_EQUAL(v[2], 3);
}

BOOST_AUTO_TEST_CASE(t_assign2) {
    using namespace boost::assign;

    push_back(v)(11)(22)(33);
    BOOST_CHECK_EQUAL(v.empty(), false);
    BOOST_CHECK_LT(v[0], v[1]);
}

BOOST_AUTO_TEST_SUITE_END()

后一个栗子的输出是

global setup
Running 2 test cases...
suit setup
suit teardown
suit setup
suit teardown
global teardown
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值