何金花 张亚红
(桂林航天工业学院 计算机科学与工程系,广西 桂林 541004)
基于继承性的面向对象类测试覆盖准则设计*
何金花**张亚红
(桂林航天工业学院 计算机科学与工程系,广西 桂林 541004)
随着面向对象软件的应用越来越广泛,面向对象软件技术的特征提高了软件开发的效率,也给软件测试带来了挑战。测试覆盖准则是软件测试的重要组成部分,可以给软件测试提供指导作用。针对面向对象继承性对软件测试的影响,从继承方法和继承属性两方面提出了类测试覆盖准则。对这两类覆盖准则进行了公理化评估,给出了算法设计,通过实例应用分析了执行结果。文中设计的覆盖准则在设计面向对象测试用例方面有一定的指导作用。
继承性;覆盖准则;软件测试;类;面向对象
软件测试是软件质量保证的重要手段,是软件开发过程中不可缺少的重要环节,也是提高软件可靠性的关键。近年来,面向对象软件开发技术越来越成熟,并得到了广泛应用和深入的研究。面向对象技术所独有的多态、继承、封装等新特点,提高了软件开发的效率,但其程序设计比传统语言程序设计产生错误的可能性增大[1],给软件测试带来了前所未有的挑战。
在进行面向对象软件测试时,如何选择测试用例,如何生成测试用例集,测试究竟进行到什么程度需要停止,这些都可以通过充分性准则来指导[2]。随着面向对象测试技术的广泛应用,越来越多的人在研究测试准则。测试覆盖准则包括行覆盖、 分支覆盖、 类覆盖、路径覆盖、状态覆盖、 迁移覆盖、迁移对覆盖、 全谓词覆盖、 全序列覆盖等。文献[3]给出了软件单元测试的覆盖充分性准则。文献[4]给出了UML状态图测试充分性准则的公理化评估,并对UML状态图上的状态覆盖、 迁移覆盖、 全谓词覆盖、N -迁移覆盖和循环分类覆盖进行了公理评估。文献[5]给出了EFSM规范测试的基本迁移覆盖准则,并进行了公理化评估。分析了该覆盖准则与基本MM路径覆盖测试覆盖准则之间的一些对应关系。
这些研究不够关注类定义的语义,对验证和确认环节也没有给予足够的重视,尤其是面向对象技术所独有的多态、 继承、 封装等新特点,产生了传统语言设计所不存在的错误可能性。因此,本文提出一种针对面向对象继承性的继承覆盖准则,包括继承方法覆盖准则、继承属性覆盖准则和子类完全覆盖准则。这些准则可以在面向对象软件继承关系类图中应用,给面向对象测试提供一定的指导作用。
面向对象继承性是指子类继承父类的特征,包括重复使用父类的属性和方法,实现代码复用。一个子类可以不再编写相同的代码,同时也可以重新定义一些属性,重写一些方法。继承的特征导致理解程序变得困难。在面向对象测试中,必须对子类进行测试。显然,对重新定义的属性和方法也是必须测试的。往往在测试子类时容易疏漏未重新定义的特征。例如:类A有方法X,类B是类A的子类,X被继承,对方法X的测试是必须的,并且测试用例要根据新的语境来重新设计。
1.1 继承方法覆盖准则
1.1.1 更新方法覆盖准则
子类的方法有三种:未重定义、重定义、新增方法。后两种称为更新方法。最基本最必要的是对子类更新方法的测试,测试范围最小,测试用例也是最少的。更新方法覆盖准则:类图中子类的每一个更新方法都要设计测试用例进行测试。不用再测试从父类继承下来的方法。
1.1.2 完全方法覆盖准则
不仅需要测试更新方法,还要在子类环境中重新测试继承下来的方法。完全方法覆盖准则:对所有父类和子类的方法都要设计测试用例进行测试。该覆盖准则比更新方法覆盖范围更广,测试用例更多。更新方法覆盖是完全方法覆盖的子集。
1.2 继承属性覆盖准则
1.2.1 更新属性覆盖准则
类似于继承性中的方法,继承属性也有三种:未重定义、重定义、新增属性。更新属性覆盖准则:类图中子类的每一个更新属性都要设计测试用例进行测试。
1.2.2 完全属性覆盖准则
完全属性覆盖准则: 类图中子类和父类的每一个属性都至少设计一个测试用例来测试。该准则的测试用例集比更新属性覆盖更广。更新属性覆盖是完全属性覆盖的子集。
1.3 子类完全覆盖准则
子类完全覆盖准则:类图中父类和子类的每一个方法和属性都至少设计一个测试用例来测试。它包含了继承方法覆盖和继承属性覆盖的测试用例集,是继承类测试覆盖中最全面的准则。
1.4 继承性覆盖准则的应用
例如:类conveyance有三个子类plane、vehicle、ship,子类分别继承conveyance类的weight(载重量)属性和transport(运输)、accelerate(加速)方法。三个子类又有自己特有的属性和方法,其中vehicle类有两个子类train和automobile,两种车辆的行驶方式不一样,因此都重写了方法run。针对这个类图,应用以上测试覆盖准则进行生成测试用例指导。类图如图1所示。
图1 conveyance类图
1.4.1 继承方法覆盖准则的应用
继承方法覆盖准则分为更新方法覆盖准则和完全方法覆盖准则2种。以vehicle类及其子类为例来应用。
更新方法覆盖准则:(1)vehicle.run(),train.run(),automobile.run()执行一遍即可满足。对于vehicle类仅执行vehicle.run()可满足。对于train类执行train.run()可满足。对于automobile类执行automobile.run()可满足。
完全方法覆盖准则:vehicle类:(2)vehicle.transport(),vehicle .accelerate (),vehicle.run()。train类:(3)train.transport(),train .accelerate (),train.run()。automobile类与train类类似。
上述分析得出结论:覆盖强度从小到大排列依次是:(1)、(2)、(3),基本能达到测试覆盖要求的是:(3)。
1.4.2 继承属性覆盖准则应用
继承属性覆盖准则分为更新属性、完全属性覆盖准则2种。以vehicle类及其子类为例应用。
更新属性覆盖准则:vehicle类:(4)vehicle.model。train类:(5)train.number,train.locomotive。
完全属性覆盖准则:vehicle类:(6) vehicle.weight, vehicle.model 。train类:(7)train.weight, train.model,train.number, train.locomotive。
上述分析得出结论:(4)是(6)的子集,(5)是(7)的子集。(6)、(7)能达到满意的覆盖要求。
1.4.3 子类完全覆盖准则应用
由于子类完全覆盖准则包含了继承方法覆盖和继承属性覆盖的测试用例集,是这两者的并集,所以可得出结论:vehicle类完全方法集(2)和完全属性集(6)的并集满足vehicle子类完全覆盖准则。train类完全方法集(3)和完全属性集(7)的并集满足train子类完全覆盖准则。
1.5 覆盖准则的评估和分析
对以上提出的继承性类测试覆盖准则,包括更新方法覆盖、完全方法覆盖、更新属性覆盖、完全属性覆盖和子类完全覆盖,共5种覆盖准则进行公理化评估,常用的公理评估属性有[4]:有限可用性,空集不充分性,单调性,最小固定尺寸性,完全性,代表性。评估结果见表1所示(√代表满足,×代表不满足)。
表1 测试覆盖准则的公理评估结果
通过评估可以得出结论:满足公理较多的是完全方法覆盖、完全属性覆盖以及子类完全覆盖3类准则。这三类覆盖准则达到了对子类的不同等级的测试要求,有较好的实用性。其它两类准则覆盖性较差。实际测试中往往只达到了更新方法和更新属性这两类最基本的覆盖,所以需要几个测试准则结合起来使用[6]。将这三类准则结合,满足了基本的覆盖,测试用例集也不是很大。
引入图的思想来表示面向对象关系的表示,用点表示事物,连接两点之间的线表示关系。类图中用三层矩形框表示类,用实线箭头来表示关联[7]。先定义三个类:Node类和Edge类,Graph类, Node类用来存放节点信息(包括Name、Kind、Attributename[MAXSIZE] 、Attributename[MAXSIZE]),Edge类存放类图中继承信息(包括fatherinfomation和soninformation)。Graph类存放类图信息(Nodenumber、Edgenumber、Node[MAXSIZE]、Edge[MAXSIZE])。
根据公理化评估结论,完全属性覆盖和完全方法覆盖比更新属性覆盖和更新方法覆盖更实用,在测试时应尽量达到完全方法和完全属性覆盖。本文针对完全方法覆盖、完全属性覆盖和子类完全覆盖设计算法。
2.1 完全方法覆盖算法
在完全方法覆盖算法设计中,创建栈Fstack用来存放类的方法,创建栈Hstrack用来存放回溯的类节点。算法如图2所示。
图2 完全方法覆盖算法图
2.2 完全属性覆盖算法
在完全属性覆盖算法中,创建栈Sstack用来存放类的属性,创建栈Hstrack用来存放回溯的类节点。算法如图3所示。
图3 完全属性覆盖准则
2.3 子类完全覆盖算法
子类完全覆盖算法是完全属性和完全方法覆盖算法的并集。算法类似图3,定义Nstack栈存放属性和方法。同时覆盖Nstack中的属性和方法就是满足子类完全覆盖。
2.4 执行结果及分析
针对conveyance类图,采用完全方法覆盖算法以及完全属性覆盖算法的运行结果分别见表2和表3。子类完全覆盖算法运行结果即完全方法覆盖结果和完全属性覆盖结果的并集。
表2 完全方法覆盖结果
表3 完全属性覆盖结果
以上结果中,方法run()在train类和automobile类的完全方法和子类完全覆盖中有重复出现,说明在子类中重写了该方法。weight属性也是如此。以上结果数据中train为例分析结果,得到属性集中属性元素train.number,train.locomotive为train类新增的属性,train .model为继承直接父类vehicle的属性,train.weight为祖先父类的属性。train类对属性的覆盖满足子类完全覆盖测试准则。train.run()为vehicle类重写的方法,train.transport() 、train.accelerate()为继承祖先父类conveyance的方法,train类对方法的覆盖满足子类完全覆盖测试准则。
通过以上分析方法可以对所有类进行分析,结果表明:(1)完全属性覆盖结果就是所有父类的属性集。(2)完全方法覆盖结果就是所有父类的方法集。(3)子类完全覆盖结果就是所有父类的属性集和方法集。(4)结果集合中,达到了相应的完全属性和完全方法覆盖准则。
本文在分析现有的面向对象软件测试覆盖准则的基础上,基于类的独有特征,给出了基于继承性的面向对象类测试覆盖准则,包括更新属性覆盖、完全属性覆盖、更新方法覆盖、完全方法覆盖、子类完全覆盖5类准则,并对5类覆盖准则进行了公理化评估,对满足公理较多的完全方法覆盖、完全属性覆盖及子类完全覆盖3类准则设计了算法,通过运行结果分析本文设计的完全方法覆盖算法、完全属性覆盖算法、子类完全覆盖算法,使其在设计测试用例时有一定的指导作用。
[1] 董洁,孙惠娟.软件测试方法及面向对象软件的测试[J].河南科技,2011(9):45-46.
[2] 杨志伟, 吴兵.基于UML状态图的软件测试充分性准则研究[J].计算机技术与发展, 2013,23(8):43-51.
[3] ZHU H,HAIL P A V,MAY J H R.Softwmm unit test coverage and adequacy[J]. ACM Computing Surveys,1997,29(4):366-427.
[4] 缪淮扣, 费立志.UML状态图测试充分性准则的公理化评估[J].上海大学学报(自然科学版),2007,13(5):489-496.
[5] 王晓峰.面向对象软件和 EFSM规范测试覆盖准则比较[J].清华大学学报 (自然科学版), 2011, 51( S1):1445-1450.
[6] 康岚兰.面向对象的软件测试方法研究[J].计算机时代,2011(10):46-48.
[7] 康维.基于UML模型的类簇级测试用例生成方法研究[D].长沙:中南大学,2009.
(责任编辑 陈葵晞)
广西教育厅科研项目《基于类语义的点态网状软件测试技术研究》(2013LX173);2013年广西教育厅科研项目《面向对象数据库在本体存储中的应用研究》(2013LX172);广西高校机器人与焊接技术重点实验室主任基金项目《基于安川焊接机器人的厚板多层多道焊接研究》(JQR2015ZR02);桂林航天工业学院科研项目《基于类语义的点态网状软件测试技术研究》(X12Z006)、《基于小波变换的图像边缘检测算法研究》(X11Z028)。
TP311.5
A
2095-4859(2016)03-0322-05
**作者简介:何金花,女,湖南浏阳人。讲师,硕士。研究方向:软件工程,软件测试。