[笔记] C++ 单元测试 (boost.test)


单元测试

在计算机编程中,单元测试(英語:)又称为模块测试,是针对程序模块(软件设计的最小单位)来进行正确性检验的测试工作。程序单元是应用的最小可测试部件。在过程化编程中,一个单元就是单个程序、函数、过程等;对于面向对象编程,最小单元就是方法,包括基类(超类)、抽象类、或者派生类(子类)中的方法。 --摘自Wiki

测试驱动开发和行为驱动开发

均摘自Wiki

测试驱动开发(英語:,縮寫為TDD)是一種软件开发过程中的應用方法,由极限编程中倡导,以其倡导先写测试程序,然后编码实现其功能得名。测试驱动开发始于20世纪90年代。测试驱动开发的目的是取得快速反馈并使用“illustrate the main line”方法来构建程序。
测试驱动开发是戴两顶帽子思考的开发方式:先戴上实现功能的帽子,在测试的辅助下,快速实现其功能;再戴上重构的帽子,在测试的保护下,通过去除冗余的代码,提高代码质量。测试驱动着整个开发过程:首先,驱动代码的设计和功能的实现;其后,驱动代码的再设计和重构。
行为驱动开发(英語:,缩写BDD)是一种敏捷软件开发的技术,它鼓励软件项目中的开发者、QA和非技术人员或商业参与者之间的协作。BDD最初是由Dan North在2003年命名,它包括验收测试和客户测试驱动等的极限编程的实践,作为对测试驱动开发的回应

boost.test快速上手

#define BOOST_TEST_MODULE your_test_module
#include 

BOOST_AUTO_TEST_CASE( case0 ) {
    BOOST_TEST( 1== 1 );
}

安装boost库后,正常编译运行即可

稍微复杂的

#define BOOST_TEST_MODULE your_test_module
#include 
#include 
#include 
#include 

using namespace std;

bool isOdd(int x) {
    return x % 2;
}

variant getName(string info)
{
    smatch groups;
    bool r = regex_match(info, groups, regex(R"(\d+\s+(\w+)\s+\w+)"));
    if(r){
        return groups[1];
    }else{
        return false;
    }
} 

// ------------Unit Test------------------

BOOST_AUTO_TEST_CASE( case0 ) {
    BOOST_TEST( isOdd(3) );
    BOOST_TEST( !isOdd(2) );
}

BOOST_AUTO_TEST_CASE( case1 ) {
    BOOST_TEST( regex_match("123", regex(R"(\d+)")) );

    auto r = getName("01 Tom Smith");
    BOOST_TEST(std::get(r) == "Tom");
}

PS: boost的编译是真的慢

如果出现错误,boost会详细提示错误位置和原因
假如我们把正则表达式的结果以0开头,boost.test就会报错:

./test.cpp(37): error: in "case1": check std::get(r) == "Tom" has failed [01 Tom Smith != Tom]

测试函数

函数 作用
BOOST_CHECK(expr) 将遇到的错误输出并继续
BOOST_CHECK_EQUAL(expr1,expr2) 检查两个表达式释放相等
BOOST_CHECK_MESSAGE(expr,msg) 将遇到的错误输出、显示msg并继续
BOOST_REQUIRE 遇到错误后终止测试
BOOST_ERROR 抛出错误并继续
BOOST_FAIL 抛出错误并终止

手动注册测试

(略)

编译速度问题

boost库很大,编译慢是硬伤
可以通过预编译头文件来尝试加速编译

  1. 将头文件集中的stdafx.h
#include 
#include 
#include 
#include 
  1. 预编译头文件
g++ -c stdafx.h -o stdafx.h.gch

3.编译cpp文件

#define BOOST_TEST_MODULE your_test_module
#include "stdafx.h"
using namespace std;

bool isOdd(int x) {
    return x % 2;
}

variant getName(string info)
{
    smatch groups;
    bool r = regex_match(info, groups, regex(R"(\d+\s+(\w+)\s+\w+)"));
    if(r){
        return groups[1];
    }else{
        return false;
    }
} 

// ------------Unit Test------------------

BOOST_AUTO_TEST_CASE( case0 ) {
    BOOST_TEST( isOdd(3) );
    BOOST_TEST( !isOdd(2) );
}

BOOST_AUTO_TEST_CASE( case1 ) {
    BOOST_TEST( regex_match("123", regex(R"(\d+)")) );

    auto r = getName("01 Tom Smith");
    BOOST_TEST(std::get(r) == "Tom");
}
g++ -include stdafx.h test.cpp

编译时间从45秒降到40秒,聊胜于无了