基于Qt_Test的单体测试方法(二)
来源:互联网 发布:逆战磁暴矩阵怎么用 编辑:程序博客网 时间:2024/04/30 08:41
2.1 数据驱动测试简介
在前一章单体测试的例子中,测试的数据只有一条,对于这个简单的被测函数来说也算够用。但是被测函数往往比较复杂,它可能包含多个分支,每个分支有不同的处理。此时应该选取多条测试数据,覆盖到被测函数所有分支。如果按照之前的做法,需要在测试函数中准备多条测试数据,执行多次被测函数并比较结果,这会使得代码臃肿不易阅读。幸好,Qt Test中提供了一种数据驱动的测试方法,能够很好地解决这个问题。
2.2 数据驱动测试方法
这种方法将原来测试函数中的处理拆分成两个部分,准备测试数据和执行被测函数,分别在数据驱动函数和测试函数中来做。数据驱动函数是一个新的函数,它也是以slot
形式存在于测试类中。它的命名有个规则:XXX_data()
,其中XXX
代表测试函数名。这种方法的思路是
- 准备测试数据
- 取出测试数据作为被测函数的输入和期待结果
- 执行被测函数得到实际输出
- 将实际输出与期待结果比较
其中第1步在数据驱动函数中进行,2,3,4步在测试函数中进行。下面对它详细介绍。
2.2.1 编写新的被测函数
首先对原来例子做些修改,编写一个复杂些的被测函数。假设Bulk_quote
继承自Quote
,它新增了两个成员:m_discount
折扣,m_minQuantity
能够打折所需的最小数量。此外,它还重写了Base类的net_price(int quantity)
,表示如果购买一定数量的书籍,则给予这个折扣。
class Bulk_quote: public Quote{public: Bulk_quote(const string& bookNo, double salePrice, int minQty, double discount): Quote(bookNo,salePrice) ,m_minQuantity(minQty) ,m_discount(discount) {} //override base function double net_price(int quantity) const { if(quantity >= m_minQuantity){ return quantity*(1 - m_discount)*m_salePrice; } else{ return quantity*m_salePrice; } }private: int m_minQuantity; double m_discount;}
2.2.2 编写数据驱动函数
测试类的编写在1.2中有过介绍,此处再写个测试类Test_Bulk_quote
,并向其中加入测试函数和数据驱动函数。按照之前的介绍,数据驱动函数名应为net_price_data()
,其中做的工作就是准备测试数据。这里的测试数据以数据集的形式存在,测试数据集可以看成是一个拥有行和列数据表格,类似于数据库中的表,这个表格中每一行代表一条测试数据,可见数据集提供了多条测试数据。Qt提供了两个方法用于添加测试数据集QTest::addColumn()
和QTest::newRow()
。
其中,QTest::addColumn(const char * name, T * dummy = 0)
是指向这个数据集添加一列,name
代表这列的名称,dummy
可以忽略。它还是一个模板函数,可以指定这列数据的类型。而QTest::newRow(const char * dataTag)
表示向数据集中添加一行测试数据,dataTag
表示这个测试case的名称,便于定位测试数据。
在1.2.3中叙述了如何编写测试函数,现在把准备测试数据移动到数据驱动函数来做(测试数据包含被测函数输入和期待结果),就不必在测试函数中编写多个测试数据了,也就解决了开头说的函数臃肿难读的问题。
被测函数输入很多,这里只用quantity
作为输入,因为类成员那些输入在构造对象时已经确定了。比如m_salePrice
为128.0元,如果购买超过10本,则9折折扣,即m_discount
为0.1,m_minQuantity
为10。
数据驱动函数的编写如下:
void Test_Bulk_quote::net_price_data(){ QTest::addColumn<int>("quantity"); QTest::addColumn<double>("result"); QTest::newRow("less than ten") << 9 << 1152.0; QTest::newRow("more than ten") << 11 << 1408.0;}
在newRow()
中<<
用于添加这行数据,其后的数据分别代表quantity
和result
列的值。在less than ten
这行数据中,表示的意思就是,如果购买9本书(不打折),期待的结果是1152.0元。
2.2.3 编写测试函数
测试函数中需要做的处理就是2.2中的2,3,4步骤。这里再介绍另一个宏QFETCH(type, name)
,它用于提取测试数据,其中type
表示数据类型,name
表示数据集中的列名,这两个参数要和数据驱动函数中的定义完全对应,不然会报错。测试函数的编写如下:
void Test_Bulk_quote::net_price(){ //get data form data set QFETCH(int, quantity); QFETCH(double, result); Bulk_quote cppPrimer("0001",128.0,10,0.1); //actual val double actual = cppPrimer.net_price(quantity); //compare qFuzzyCompare(actual,result);}
如前所述,构造Bulk_quote
时,将它的所有成员都确定了。执行这个测试类时,数据驱动函数被执行一次,而测试函数被执行两次,因为数据集中有两条测试数据。
以上就是数据驱动测试的方法,这个方法将准备测试数据和执行被测函数分而治之,减少了代码间的耦合。在应用Qt Test时,尽量都采用这种方法,灵活运用QTest::addColumn()
,QTest::newRow()
和Q_FETCH
等框架函数和宏,就能更大程度发挥Qt Test的功能了。
- 基于Qt_Test的单体测试方法(二)
- 基于Qt Test的单体测试方法(一)
- 单体测试
- 单体测试的代码覆盖率工具cobertura
- 单体测试书的检查要点
- Xcode4单体测试结果覆盖率的确认方法
- 单体测试和结合测试相关的总结
- 基于Web的系统测试分析与测试方法(二)
- 单体测试指导
- 单体测试工具集锦
- PHP单体测试自动化
- 单体测试 观点
- Junit单体测试
- 单体测试指南
- Eclipse 单体测试
- 写单体测试
- 单体测试培训
- Junit 单体测试
- 深入理解Java:自定义注解入门(Annotation)
- 静态路由算法
- linux文件描述符与打开文件的关系
- MFC之多线程
- 剑指offer经典编程(十七)
- 基于Qt_Test的单体测试方法(二)
- python学习记录1
- 使用Spring AOP切面解决数据库读写分离
- python函数的5种参数
- 网站整体变灰色的css代码
- Hadoop家族学习路线图
- <2>python学习笔记——分支和循环
- SQL高级语句-BETWEEN 操作符在 WHERE 子句中使用,作用是选取介于两个值之间的数据范围。
- MYSQL 备份方案