两种混合型软件单元的测试方法

2011-04-17 07:29勾英杰江云松
空间控制技术与应用 2011年3期
关键词:黑盒单元测试测试用例

勾英杰,江云松

(北京控制工程研究所,北京 100190)

软件测试是保证软件质量和可靠性的重要手段之一,软件单元测试作为软件测试的一个环节,起着极其重要的作用.

单元测试也称模块测试,完成对最小的软件设计单元——模块的验证工作,它是软件开发过程中最基础的测试活动,其目的主要是发现在编码过程中引入的错误和验证代码与设计的符合性.充分的单元测试对发现和排除软件中的缺陷非常有效,并且由于它处于软件生存期的早期,所花费的成本也小.

目前航天领域对软件单元测试已经引起了足够的重视,并引入了一些自动化的测试工具,但由于航天器控制软件是非常复杂的实时嵌入式软件,工作模式多,与硬件结合密切,单元测试工作量大、测试难度高,仍需研究和应用有效的测试方法,设计高质量的测试用例,才能使单元测试阶段发现错误的能力提高.

本文将结合航天器控制计算机软件单元测试的具体实践,重点介绍白盒技术与黑盒技术相结合的两种单元测试方法.

1 单元测试方法概述

在软件单元测试过程中,静态测试和动态测试是两种非常有效的测试技术.静态测试是指不运行被测程序,仅通过分析或检查源程序的算法、结构、过程接口等等来检查程序的正确性,可以通过人工走查(walkthroughs)和代码审查(inspections)的方式进行,还可以借助静态分析工具进行;动态测试是指通过运行被测程序,检查运行结果与预期结果的差异,并分析运行效率和健壮性.动态测试的过程由三部分组成:设计测试用例、执行程序和分析程序输出结果.

目前的许多单元测试工具(如,LDRA的Testbed,IBM的Rational Test RealTime,英国 IPL公司的Cantata,等等)对于动态测试的后两个环节提供了很大帮助,而对于测试过程中的关键环节——测试用例设计还得由人来完成,测试用例设计的好坏,直接影响到单元测试的效果,因此,有必要对测试用例的设计方法进行研究.动态测试按照测试用例的不同设计方法分为黑盒测试和白盒测试,本文着重分析这两种测试技术.

白盒测试又称结构测试、逻辑驱动测试或基于程序的测试.它针对程序的内部结构和内部特性,测试者可以完全不考虑程序的功能,只利用程序内部的逻辑结构及有关信息设计测试用例;黑盒测试又称功能测试、数据驱动测试或基于规格说明的测试.它针对程序的外部特性,在完全不考虑程序内部结构和内部特性的情况下,只依据程序的规格说明考虑确定测试用例,检查程序的功能是否符合它的功能说明.表1将黑盒测试和白盒测试进行了比较.

由表1可知,白盒测试与黑盒测试在选取测试用例的侧重点不同,白盒测试侧重于程序的内部结构,黑盒测试侧重于程序的功能,因而两种方法各有优缺点,不能相互代替.Beizer在总结功能测试和结构测试时指出“从原理上讲,功能测试能检测出所有的错误,但需要花费无数的时间;结构测试本质上是有限的,但即使是全部执行也不能测试出全部的错误.在某种程度上讲,测试的艺术就是在结构测试与功能测试之间如何进行选择”.

充分性和有效性是测试用例生成时需要重点考虑的问题.测试用例的充分性一般可以通过测试覆盖准则来衡量,测试覆盖准则可以指导测试用例的选择,避免测试的盲目性,保证软件测试的充分性.而有效性则是指如何以最小的代价获得尽可能好的测试用例.

2 两种混合型的单元测试方法

如上所述,白盒与黑盒测试用例设计方法具有各自的优缺点,为充分利用两种测试技术的优点和弥补各自的不足,在进行软件单元测试用例的设计时,要结合这两种测试技术,重点考虑测试用例的充分性和有效性.

针对不同的软件单元,采用以下两种混合型的单元测试用例选择方法,会在尽量满足测试的充分性和有效性的前提下,提高单元测试的效率和效果.需要说明的是,不管哪一种方法,其测试用例的设计依据都是软件设计规约,即各个软件单元的详细设计报告,只有这样才能使单元测试成为基于设计的测试.

2.1 先黑盒后白盒的单元测试方法

先黑盒后白盒的用例选择方法,就是先采用黑盒测试技术生成测试用例,然后用一种或多种白盒技术对模块单元的逻辑结构进行分析,对现有的测试用例进行补充,最后得到一个合理而严格的测试用例集.黑盒测试技术中的等价类划分和边界值分析是比较简单而又有效的方法,用白盒测试技术补充用例时,可以按照不同的覆盖准则选择不同的覆盖技术.该测试用例选择方法的流程如图1所示.

图1 先黑盒后白盒的单元测试用例选择方法

2.1.1 等价类划分设计用例

首先,使用等价类划分设计测试用例.

等价类划分是一种常用的黑盒测试方法,该方法将程序的输入域划分为若干个等价类,以便导出测试用例.每个等价类中的一个典型值在测试中的作用与这一类中所有其他值的作用相同,因此,可以从每个等价类中只取一组数据作为测试数据.这样选取的测试数据最有代表性,最可能发现程序中的错误.

等价类划分需要研究程序的功能说明,从而确定输入数据的有效等价类和无效等价类.典型地,输入条件通常是一个特定的数值,一个数值域,一组相关值或一个布尔条件.可按照如下规则定义等价类:

①如果输入条件代表一个范围,可以定义一个有效等价类(输入值在此范围内)和两个无效等价类(输入值小于最小值或大于最大值).

②如果输入条件需要特定个数的值,可以定义一个有效等价类(输入值符合特定个数)和两个无效等价类(输入值少于或多于特定个数).

③如果输入条件代表集合的某个元素,可以定义一个有效等价类(输入值属于集合)和一个无效等价类(输入值不属于集合).

④如果输入条件是布尔式,可以定义一个有效等价类和一个无效等价类.

2.1.2 边界值分析补充用例

等价类划分设计出测试用例后,要使用边界值分析补充用例.

边界值分析也是一种黑盒测试方法.经验表明,输入域的边界比中间更加容易发生错误,为此,边界值分析是一种补充等价类划分的测试用例设计技术.边界值分析不是选择等价类的任意元素,而是选择等价类边界的测试用例,边界值分析不仅注重于输入条件,而且也从输出域导出测试用例.

按照边界值分析的方法,应该选取刚好等于、稍小于和稍大于等价类边界的数据作为测试数据.

通常设计测试用例时总是联合使用等价类划分和边界值分析两种技术.

2.1.3 逻辑覆盖检查最后,使用逻辑覆盖准则,对测试用例进行补充.逻辑覆盖是最常用的一类白盒测试方法.各逻辑覆盖的覆盖强弱顺序如图2所示.

图2 逻辑覆盖之间的关系

覆盖率统计和分析的工作可以借助工具完成.当通过上述黑盒测试方法设计的测试用例没有达到规定的覆盖率时,就要为未覆盖的分支或路径设计补充测试用例.

2.2 先白盒后黑盒的单元测试方法

先白盒后黑盒的用例选择方法,是在设计测试用例时,首先关注模块内部的逻辑分支和路径的执行情况,即首先采用白盒测试中的逻辑覆盖技术,选择出即将执行的分支或路径,再结合黑盒测试方法,确保每一个分支或每一条基本路径域中的测试用例都能验证单元模块的功能,当满足规定的覆盖准则后,再次利用黑盒测试对用例进行补充.这样,在满足测试用例的充分性的前提下,又能尽量保证其有效性.

在白盒测试中,根据不同的测试覆盖准则,可以选择图3中介绍的各种覆盖技术,由图3可知,路径覆盖是一种最强的逻辑覆盖,基本路径覆盖测试方法是一种常用的、有效的路径覆盖技术,它将程序中的循环体只执行零次和一次.它是在程序控制流图的基础上,通过分析控制流程的圈复杂度,导出基本路径集合,从该基本路径集合导出测试用例,保证对程序中的每一条语句和分支都至少执行一次.目前的许多软件静态测试工具都能给出程序的控制流图,这为设计测试用例提供了方便.

图3 先白盒后黑盒的单元测试用例选择方法

对于由基本路径测试方法中导出的每一条基本路径上的测试用例的选取,可以使用等价类划分和边界值分析,弥补单纯采用白盒测试的某些不足(如,没有提供在一个路径域中选择测试数据的原则[3]),使每一个测试用例都更加有效.

该方法的流程如图3所示,图中的白盒测试选用基本路径测试方法,黑盒测试选用等价类划分和边界值分析的方法.

2.2.1 基本路径法导出基本路径集合

基本路径测试,又被称为结构化测试方法(the structured testing approach),是一种白盒测试技术,基本路径测试方法允许测试用例设计者导出一个过程设计的逻辑复杂性度量,并使用该度量作为指南来定义执行路径的基本集.从该基本集导出的测试用例不仅能够保证对程序中的每一条语句至少执行一次,还使得每一个判定的结果(取真和取假)都被独立的测试过.

根据图论,基本路径测试方法中所需的测试用例数,也就是基本路径集合中的独立路径条数,等于程序的圈复杂度(cyclomatic complexity)v(G).圈复杂度v(G)可以用以下3种方法求得:

1)v(G)=程序的控制流图中的区域数

2)v(G)=E-N+2,其中,E为控制流图的边数,N为图的节点数

3)v(G)=P+1,P为控制流图中的判定节点数

值得一提的是,圈复杂度v(G)几乎与编程语言无关,因为有相同逻辑结构的程序,不管用哪一种面向过程的语言实现,所得到的基本判定结构都是相同的.这是由于控制流图中的判定节点不包含复合条件,例如C语言实现的程序中的复合条件在生成控制流图时会将复合条件分解成各个子条件.

大量研究表明,圈复杂度度量与软件模块中的错误数相关联,在其他因素相同情况下,复杂的模块代码比简单的代码中出现错误的可能性要大[4].并且,与高级语言相比,低级语言中的这种可能性更大一些.

2.2.2 为每一条基本路径选择用例

准备测试用例,强制执行基本路径集中每条路径.这时要结合等价类划分和边界值分析方法,选择数据以便在测试每条路径时适当设置判定节点的条件.

2.2.3 黑盒测试方法补充用例

最后,还要使用等价类划分和边界值分析方法,对上述生成的测试用例进行补充.

2.3 两种方法讨论

两种单元测试方法将黑盒测试与白盒测试相结合,既免去了单纯用白盒测试方法生成用例时只关注程序内部结构而忽略模块功能,又弥补了单纯用黑盒测试时难以达到较高的覆盖率的不足,并且,两种方法都有利于实现并行开发,在软件设计阶段即可组织人员进行单元测试用例的设计,可以达到先测试设计后编码的目的,能够发现软件设计阶段的错误.

先黑盒后白盒方法生成测试用例的好处主要是:首先使用黑盒方法,直接关注模块的功能,能够提高测试用例的有效性;白盒测试方法放在黑盒测试之后,进一步提高了测试效率,当单纯用黑盒方法设计测试用例进行到一定阶段时,再设计新的测试用例会比较费力,而此时如果借助静态覆盖分析工具,白盒测试用例的设计就比较容易了.这种测试用例选择方法,适合实现功能非常明确、内部实现逻辑相对复杂的模块单元.

先白盒后黑盒的用例选择方法在不了解程序模块功能的情况下便开始用例的设计,从分析程序内部结构和程序执行路径的基础上结合黑盒测试方法,弥补了单纯用白盒测试时难以保证用例有效性的不足.这种用例选择方法,适合模块实现功能不很清晰或测试人员对模块的功能不能很好理解的情况下,也适用于内部逻辑相对简单、算法相对复杂的单元模块.

这两种方法已被应用于某航天型号计算机应用软件的单元测试中,取得了很好的效果.我们通过对单元测试方法的研究和具体实践,得出以下结论:

1)单元测试用例必须根据详细设计报告进行设计,这样设计出的用例具有更强的揭错能力.

2)不能片面追求单纯的100%覆盖率,为测试而测试,要兼顾模块的功能、性能要求设计用例,并针对出错概率高的代码设计专门的测试用例.

3)在进行模块的详细设计时,就要考虑测试用例的设计.通过模块的合理设计降低模块的复杂度,将会大大降低测试的工作量,并提高整个软件的质量.

4)黑白盒相结合的测试用例设计方法在单元测试中是非常有效的.应用这些方法认真的进行测试用例的设计,才能从根本上提高单元测试的效率和效果.

3 结束语

作为保证软件质量和可靠性的重要手段之一,软件测试已逐渐成为现代软件工程学研究和应用的热点.单元测试与其它阶段测试相比,其投入较小,回报却很高,它为后续测试工作提供了重要保障.因此,在实际工作中深入研究和应用有效的软件单元测试方法,这对于保证和提高航天软件的质量具有重要的现实意义.本文主要针对航天器控制软件的单元测试方法进行了一些探索,在实践中总结出的两种混合型的单元测试用例设计方法,对于提高单元测试的效果具有现实指导作用,但方法的使用还主要依靠人来完成,这将对人员的素质要求较高.因而,探讨测试用例的自动生成技术,提高单元测试的自动化程度,将是下一步将要解决的问题.

[1] 郑人杰,计算机软件测试技术[M].北京:清华大学出版社,1992

[2] Roger S P著,梅宏译.软件工程-实践者的研究方法(原书第5版)[M].北京:机械工业出版社,2002

[3] Simeon C N.A comparison of some structural testing strategies[J].IEEE Transactions on Software Engineering,1988,14(6):868-874

[4] Arthur H W,Thomas J M.Structured testing:a testing methodology using the cyclomatic complexity metric[M].NIST Special Publication,1996

猜你喜欢
黑盒单元测试测试用例
一种基于局部平均有限差分的黑盒对抗攻击方法
测试用例自动生成技术综述
回归测试中测试用例优化技术研究与探索
基于SmartUnit的安全通信系统单元测试用例自动生成
一年级上册第五单元测试
一年级上册一、二单元测试
第五单元测试卷
第六单元测试卷