了解 Boost 单元测试框架Word文档下载推荐.docx
- 文档编号:20827107
- 上传时间:2023-01-25
- 格式:DOCX
- 页数:17
- 大小:23.09KB
了解 Boost 单元测试框架Word文档下载推荐.docx
《了解 Boost 单元测试框架Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《了解 Boost 单元测试框架Word文档下载推荐.docx(17页珍藏版)》请在冰豆网上搜索。
intsize(){returnlength;
};
#endif
与字符串相关的一些典型的检查,会验证空字符串的长度是否为0,访问范围超出索引是否导致错误消息或异常,等等。
清单2
给出了一些值得为任何字符串实现创建的测试。
要想运行
中的源代码,只需用g++(或任何符合标准的
编译器)编译它。
注意,不需要单独的主函数,代码也不使用任何链接库:
作为Boost一部分的unit_test.hpp头文件中包含所需的所有定义。
清单2.字符串类的单元测试
#defineBOOST_TEST_MODULEstringtest
#include<
boost/test/included/unit_test.hpp>
#include"
./str.h"
BOOST_AUTO_TEST_SUITE(stringtest)//nameofthetestsuiteisstringtest
BOOST_AUTO_TEST_CASE(test1)
{
mystrings;
BOOST_CHECK(s.size()==0);
}
BOOST_AUTO_TEST_CASE(test2)
s.setbuffer("
helloworld"
);
BOOST_REQUIRE_EQUAL('
h'
s[0]);
//basictest
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE
和
BOOST_AUTO_TEST_SUITE_END
宏分别表示测试套件的开头和结尾。
各个测试放在这两个宏之间,从这一点来看,这些宏的语义很像
名称空间。
每个单元测试用
BOOST_AUTO_TEST_CASE
宏来定义。
清单3
给出了
中代码的输出。
清单3.清单2中代码的输出
[arpan@tintin]./a.out
Running2testcases...
test.cpp(10):
errorin"
test1"
:
checks.size()==0failed
***1failuredetectedintestsuite"
stringtest"
下面详细讨论如何创建前面清单中的单元测试。
基本思想是使用Boost提供的宏来测试各个类特性。
BOOST_CHECK
和BOOST_REQUIRE_EQUAL
是Boost提供的预定义宏(也称为测试工具),用于验证代码输出。
Boost测试工具
Boost有一整套测试工具,基本上可以说它们是用于验证表达式的宏。
测试工具的三个主要类别是
BOOST_WARN、BOOST_CHECK
和BOOST_REQUIRE。
BOOST_REQUIRE
之间的差异在于:
对于前者,即使断言失败,测试仍然继续执行;
而对于后者,认为这是严重的错误,测试会停止。
清单4
使用一个简单的
片段展示了这些工具类别之间的差异。
清单4.使用Boost测试工具的三个变体
#defineBOOST_TEST_MODULEenumtest
BOOST_AUTO_TEST_SUITE(enum-test)
typedefenum{red=8,blue,green=1,yellow,black}color;
colorc=green;
BOOST_WARN(sizeof(green)>
sizeof(char));
BOOST_CHECK(c==2);
BOOST_REQUIRE(yellow>
red);
BOOST_CHECK(black!
=4);
第一个
会失败,第一个
也是如此。
但是,当
失败时,代码退出,所以不会到达第二个BOOST_CHECK。
清单5
显示了
清单5.理解BOOST_REQUIRE和BOOST_CHECK之间的差异
Running1testcase...
e2.cpp(11):
checkc==2failed
e2.cpp(12):
fatalerrorin"
criticalcheckyellow>
redfailed
***2failuresdetectedintestsuite"
enumtest"
同样,如果需要针对特定情况检查某些函数或类方法,最容易的方法是创建一个新测试,并使用参数和期望值调用这个例程。
清单6提供了一个示例。
清单6.使用Boost测试检查函数和类方法
BOOST_AUTO_TEST(functionTest1)
BOOST_REQUIRE(myfunc1(99,‘A’,6.2)==12);
myClasso1(“helloworld!
\n”);
BOOST_REQUIRE(o1.memoryNeeded()<
16);
模式匹配
经常需要根据“黄金日志”测试函数生成的输出。
也适合执行这种测试,这还需要用到Boost库的
output_test_stream类。
用黄金日志文件(以下示例中的run.log)初始化
output_test_stream。
函数的输出被提供给这个
output_test_stream
对象,然后调用这个对象的
match_pattern
例程。
清单7
提供了详细代码。
清单7.根据黄金日志文件执行模式匹配
#defineBOOST_TEST_MODULEexample
boost/test/output_test_stream.hpp>
usingboost:
test_tools:
output_test_stream;
BOOST_AUTO_TEST_SUITE(test)
BOOST_AUTO_TEST_CASE(test)
output_test_streamoutput("
run.log"
true);
output<
<
predefined_user_func();
BOOST_CHECK(output.match_pattern());
浮点比较
回归测试中最棘手的检查之一是浮点比较。
请看一下
清单8,看起来没什么问题—至少从表面看是这样。
清单8.无效的浮点比较
#defineBOOST_TEST_MODULEfloatingTest
cmath>
floatf1=567.0102;
floatresult=sqrt(f1);
//thiscouldbemy_sqrt;
fasterimplementation
//forsomespecificDSPlikehardware
BOOST_CHECK(f1==result*result);
运行这个测试时,尽管使用的是作为标准库一部分提供的
sqrt
函数,BOOST_CHECK
宏仍然会失败。
什么地方出错了?
浮点比较的问题在于精度—
f1
result*result
在小数点后面的几位不一致。
为了解决这个问题,Boost测试实用程序提供了BOOST_WARN_CLOSE_FRACTION、BOOST_CHECK_CLOSE_FRACTION
BOOST_REQUIRE_CLOSE_FRACTION
宏。
要想使用这三个宏,必须包含预定义的Boost头文件floating_point_comparison.hpp。
这三个宏的语法是相同的,所以本文只讨论check变体(见
清单9)。
清单9.BOOST_CHECK_CLOSE_FRACTION宏的语法
BOOST_CHECK_CLOSE_FRACTION(left-value,right-value,tolerance-limit);
清单9
中没有使用
BOOST_CHECK,而是使用
BOOST_CHECK_CLOSE_FRACTION
并指定公差限制为0.0001。
清单10
给出了代码现在的样子。
清单10.有效的浮点比较
boost/test/floating_point_comparison.hpp>
floatf1=567.01012;
BOOST_CHECK_CLOSE_FRACTION(f1,result*result,0.0001);
这段代码运行正常。
现在,把
中的公差限制改为0.0000001。
清单11
给出了输出。
清单11.由于超过公差限制,比较失败
sq.cpp(18):
test"
differencebetweenf1{567.010132}and
result*result{567.010193}exceeds1e-07
floatingTest"
生产软件中另一个常见的问题是比较
double
float
类型的变量。
的优点是它不允许进行这种比较。
这个宏中的左值和右值必须是相同类型的—即要么是
float,要么是
double。
在
清单12
中,如果
是double,而
result
是float,在比较时就会出现错误。
清单12.错误:
BOOST_CHECK_CLOSE_FRACTION的左值和右值参数的类型不同
[arpan@tintin]g++sq.cpp-I/u/c/lib/boost
/u/c/lib/boost/boost/test/test_tools.hpp:
Infunction
`boolboost:
tt_detail:
check_frwd(Pred,
constboost:
unit_test:
lazy_ostream&
boost:
const_string,size_t,
tool_level,
check_type,
constArg0&
constchar*,
constArg1&
constchar*,constArg2&
constchar*)
[withPred=boost:
check_is_close_t,Arg0=double,
Arg1=float,Arg2=boost:
fraction_tolerance_t<
double>
]'
sq.cpp:
18:
instantiatedfromhere
523:
error:
nomatchforcallto
`(boost:
check_is_close_t)(constdouble&
constfloat&
&
)'
定制的断言支持
Boost测试工具验证Boolean条件。
可以通过扩展测试工具支持更复杂的检查—例如,判断两个列表的内容是否相同,或者某一条件对于向量的所有元素是否都是有效的。
还可以通过扩展
宏执行定制的断言检查。
下面对用户定义的
函数生成的列表内容执行定制的检查:
检查结果中的所有元素是否都大于1。
定制检查函数需要返回
boost:
predicate_result
类型。
清单13
给出了详细的代码。
清单13.使用Boost测试工具验证复杂的断言
predicate_resultvalidate_list(std:
list<
int>
L1)
{
std:
iteratorit1=L1.begin();
for(;
it1!
=L1.end();
++it1)
{
if(*it1<
=1)returnfalse;
returntrue;
list1=user_defined_func();
BOOST_CHECK(validate_list(list1));
对象有一个隐式的构造函数,它接受一个Boolean值,因此即使
validate_list
的期望类型和实际返回类型不同,代码仍然会正常运行。
还有另一种用Boost测试复杂断言的方法:
BOOST_CHECK_PREDICATE
这个宏的优点是它不使用
predicate_result。
但缺点是语法有点儿粗糙。
用户需要向
宏传递函数名和参数。
清单14
的功能与
相同,但是使用的宏不同。
注意,validate_result
的返回类型现在是Boolean。
清单14.BOOST_CHECK_PREDICATE宏
boolvalidate_list(std:
BOOST_CHECK_PREDICATE(validate_list,list1);
在一个文件中包含多个测试套件
可以在一个文件中包含多个测试套件。
文件中定义的每个测试套件必须有一对
BOOST_AUTO_TEST_SUITE...BOOST_AUTO_TEST_SUITE_END
清单15
给出了在同一个文件中定义的两个测试套件。
在运行回归测试时,用预定义的
–log_level=test_suite
选项运行可执行程序。
清单16
中可以看到,使用这个选项生成的输出很详细,有助于进行快速调试。
清单15.使用一个文件中的多个测试套件
#defineBOOST_TEST_MODULERegression
typedefstruct{
intc;
chard;
doublee;
boolf;
}Node;
typedefunion{
}Node2;
BOOST_AUTO_TEST_SUITE(Structure)
BOOST_AUTO_TEST_CASE(Test1)
Noden;
BOOST_CHECK(sizeof(n)<
12);
BOOST_AUTO_TEST_SUITE_END()
BOOST_AUTO_TEST_SUITE(Union)
Node2n;
BOOST_CHECK(sizeof(n)==sizeof(double));
下面是
中代码的输出:
清单16.用–log_level选项运行多个测试套件
[arpan@tintin]./a.out--log_level=test_suite
Enteringtestsuite"
Regression"
Structure"
Enteringtestcase"
Test1"
m2.cpp(23):
checksizeof(n)<
12failed
Leavingtestcase"
Leavingtestsuite"
Union"
理解测试套件的组织
到目前为止,本文已经讨论了Boost测试实用程序和没有层次结构的测试套件。
现在,我们使用Boost创建一个测试套件,以外部工具用户常见的方式测试软件产品。
在测试框架中,通常有多个套件,每个套件检查产品的某些特性。
例如,文字处理程序的回归测试框架应该包含检查字体支持、不同的文件格式等方面的套件。
每个测试套件包含多个单元测试。
清单17
提供了一个测试框架示例。
注意,代码入口点必须是名为
init_unit_test_suite
的例程。
清单17.创建用于运行回归测试的主测试套件
#defineBOOST_TEST_MODULEMasterTestSuite
unit_test;
test_suite*
init_unit_test_suite(intargc,char*argv[])
test_suite*ts1=BOOST_TEST_SUITE("
test_suite1"
);
ts1->
add(BOOST_TEST_CASE(&
test_case1));
add(BOOST_TEST
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 了解 Boost 单元测试框架 单元测试 框架