软件测试关键技术的研究与应用

2014-06-23 06:39李国强王海瑞
火控雷达技术 2014年2期
关键词:测试数据测试用例等价

李国强 张 虹 王海瑞

(1.西安电子工程研究所 西安 710100;2.装甲兵军事代表局驻西安地区军事代表室 西安 710000)

0 概述

随着计算机技术的广泛应用,在军工武器装备的研制中从系统级到部件级都采用了大量的计算机硬件和软件,这些软硬件组合在一起实现武器装备的功能。在这样的系统中无论硬件还是软件都存在设计缺陷与错误,有可能引起装备的故障,甚至可能造成严重损失。

随着软件的规模和复杂度的增加,在软件开发的各个阶段中,产生错误的时机很多,如软件需求的叙述、软件架构的设计、软件编码都可能产生错误;就连程序输入也可能引入错误,软件错误造成的灾难也越来越严重。

国内外已有大量事例说明,当代武器装备的大量灾难性事故是由软件故障引起的,如何减少软件缺陷成为软件界面临的严峻挑战。软件测试是发现软件错误和缺陷的最好的方法,也是保证软件质量的关键手段,因此开展软件测试技术的研究已引起了国内外软件业的高度重视。

1 软件测试的分类

软件测试是为了发现代码中的错误而分析或执行代码的过程,是保证软件质量及可靠性的手段,能够为产品设计定型提供依据。对于软件测试,可以从下面几种不同的角度分类:

从是否需要执行被测试软件的角度分类,可以分为静态测试和动态测试。如果在测试过程中执行被测试软件,则称之为动态测试,相反,在测试过程中不执行被测试软件,则称之为静态测试。

从测试是否针对软件结构预算法的角度分类,分为白盒测试、黑盒测试。若在测试过程中,不关心软件的内部结构和具体的实现算法,在无需了解软件结构预算法的情况下进行测试,则称之为黑盒测试,反之,如果需要对软件的内部结构和算法进行测试,则称之为白盒测试。

根据软件研制的过程,在不同的软件研制阶段所要关注的点不同,采用的测试技术也不同,因此软件的软件测试工作本身也要按照阶段进行,在每个阶段有着不同的测试方法,整个测试过程可以分为单元测试、集成测试、系统测试和验收测试和回归测试等五个阶段(见表1)。

表1 软件测试技术分类

2 软件测试技术

2.1 静态测试技术

静态测试又称静态分析,静态测试是不执行软件程序而寻找文档、代码中可能存在的缺陷或评估程序代码的过程[1]。静态测试可以人工进行,也可以借助专门的软件测试工具自动进行。静态测试主要包括由人工进行文档审查、代码走查以及由软件工具自动进行的工具辅助静态分析。

2.1.1 文档审查

文档审查遵循软件同仁审查的方法和过程,即组成评审组,对照软件需求规格说明、软件设计说明检查单检查需求、设计易出现的错误。

审查软件需求规格说明着重于检查软件需求是否符合系统需求,软件需求的描述和解释是否完整、准确等。主要审查的内容如下:

a.软件需求与系统需求的符合性;

b.软件需求的准确性及一致性;

c.软件需求与目标机的兼容性;

d.软件需求的可测试性;

e.软件需求与所依标准的符合性;

f.软件需求到系统需求的可追踪性;

g.算法的准确性。

审查软件设计说明着重于分析设计是否与需求定义一致,所采用的数值方法和算法是否适用于待解问题,对软件的划分是否与待解问题相适应,需求是否都被满足了等。主要审查的内容如下:

a.软件设计与软件需求的符合性;

b.软件设计的准确性和一致性;

c.软件设计与目标机的兼容性;

d.软件设计的可测试性;

e.软件设计与编写标准的符合性;

f.软件设计到软件需求的可追踪性;

g.算法的准确性;

h.控制流描述的正确性;

i.数据设计说明的完备性、一致性的和易理解性;

j.软件具有健壮性;

k.软件划分的完整性;

l.可靠性、安全性设计的恰当性。

2.1.2 代码走查

代码走查是早期可以开展的测试活动,是发现软件错误的有效手段,在开发过程中可以通过开评审会的形式开展。参照代码检查单检查编码中易出现的错误,检查代码和设计的一致性,代码对标准的遵循、可读性,代码的逻辑表达的正确性,代码结构的合理性等方面;可以发现违背程序编写标准的问题,程序中不安全、不明确和模糊的部分,找出程序中不可移植部分、违背程序编程风格的问题,包括变量检查、命名和类型审查、程序逻辑审查、程序语法和程序结构检查等内容。程序逻辑检查一般有两种审查方法,即深度优先遍历和广度优先遍历方法。深度优先遍历通过追踪每个子程序的主要逻辑行,将主要逻辑行全部追踪完,然后再开始追踪第二条路径。广度优先遍历从主要行开始,按排列顺序依次检查较低层的程序段。广度优先遍历有助于很快了解程序全貌,深度优先遍历适于详细查阅功能处理步骤[2]。

2.1.3 静态分析

静态分析是一种利用测试工具对代码进行的机械性和格式化的分析方法。静态分析速度快,工作质量稳定,可在现性强;静态分析可以只分析某些特定的缺陷,或只分析某些特定的模块,而不会受到其它缺陷和其他模块的影响。静态分析主要包括:包括控制流分析、数据流分析、接口分析、表达式分析。

控制流分析:控制流图是一宗表示程序控制结构的有向图,可用于说明程序的逻辑路径。如果一个输入引起一条路径的执行,那么这条路径就成为可达,否则不可达;控制流分析能检测出程序是否存在不可达和死循环的情况。

数据流分析:数据流分析是通过检查变量的定义和引用关系来发现程序中的错误;如果程序中某一条语句的执行能改变某个变量的值,则称这个变量在该语句中定义;如果某一条语句的执行引用了某变量的值,则称这条语句引用了该变量;通过定义和引用的关系,可以发现数据流的异常。

接口分析:接口分析主要用在程序静态分析和设计分析。接口设计分析涉及模块之间接口的一致性以及模块与外部数据库之间的一致性。接口分析涉及子程序以及函数之间的接口一致性,包括检查形参与实参类型、个数、维数、顺序的一致性。当程序模块之间的数据或控制传递使用公共变量块或全局变量时,也应检查它们的一致性。

表达式分析:某些错误的出现与程序中表达式的计算相关。如果进行对表达式的分析,就可以避免这些错误。表达式错误主要有以下几种:括号使用不正确,数组应用错误,作为除数的变量可能为零,作为开平方的变量可能为负数,作为正切值的变量为∏/2,浮点数变量比较时产生的错误。

2.2 动态测试技术

动态测试是建立在对程序的执行过程中,根据是否对被测对象内部的了解,分析输出以发现错误的过程,如果抽样测试数据满足一定要求,通过测试可以发现程序中大多数错误,并且可以评估程序的质量(正确性、可靠性等)。动态测试技术具有以下特点:

a.实际运行被测试程序,获取程序运行的真实情况、动态情况并进行分析;

b.必须设计测试数据来运行程序,测试质量依赖于设计的测试数据;

c.设计测试数据、分析测试结果工作量大,使开展测试工作费时、费力;

d.动态测试中涉及多方面工作,人员多、设备多、数据多,要求有较好的管理和工作规程。

动态测试包括三部分核心内容:设计测试数据、执行程序及验证程序的输出结果。围绕核心还有文件编制、数据管理、操作规程化及工具应用等方面工作,其中最重要的问题是设计测试数据的策略,它是动态测试有效、高效的关键。动态测试主要有黑盒测试和白盒测试。黑盒测试和白盒测试实际上是测试数据选择的两种方式[3]。

任何工程产品都可以使用以下的两种方法之一进行测试:已知产品的功能设计规格,通过测试证明实现的每个功能是否符合要求;已知产品的内部工作过程,通过测试证明每种内部操作是否符合设计规格要求,所有内部成分是否已经经过验证。这两种立场不同的测试,就是常用的两种测试方法:黑盒测试与白盒测试。

2.2.1 黑盒测试(Black-box Testing)

黑盒测试又称功能测试,是一种按照软件需求规格说明设计测试数据的方法。它把程序看作内部不可见的黑盒子,完全不需考虑程序内部结构和内部特征,测试者只需了解程序输入和输出之间的关系,或是程序的功能,完全依靠需求规格说明确定测试数据,判定测试结果的正确性。黑盒测试方法有等价类划分、边界值分析、随机测试等测试用例设计方法。

2.2.1.1 等价类划分

因为要使用穷举输入进行测试是不可能的。因此,人们在设计测试用例时,试图局限于使用输入的一个小子集进行测试。在选择这个小子集时,又希望它是发现错误概率最大的子集。一个基本的原则就是这个有限子集应能代表所有可能的输入全集。按照这个思路,我们把输入全集划分为若干等价类,这样就有可能得到一种假设,即测试某等价类的代表值就等价于对这一类其它值的测试。也就是说,如果某个等价类中的一个测试用例查出了错误,这一等价类中的其它测试用例也会查出同样的错误。反之,若某个等价类中的测试用例未查出错误,那么,这一等价类中的其它测试用例也同样查不出错误。等价类划分就是这种划分输入全集的技术,它可导致发现不同错误种类的测试用例设计,以减少所需的测试用例总数。

采用等价类划分技术设计测试用例分两个步骤:划分等价类和确定测试用例。

划分等价类的方法是根据每个输入条件(通常是需求规格说明中的一句话或一个短语)找出等价类。划分等价类时,必须仔细分析和推敲需求规格说明中的每一项需求,特别是功能需求,不但要考虑每个输入条件,也要考虑每个输出条件。

等价类划分可分为两种不同的情况:有效等价类和无效等价类。有效等价类指的是对于程序的需求规格说明是合理的、有意义的输入数据构成的集合。利用有效等价类可检验程序是否实现了需求规格说明中规定的功能和性能。无等价类指的是对软件需求规格说明而言是不合理或无意义的输入数据所构成的集合。表2是一个等价类划分的列子,H、M、S作为当前系统时间。

表2 等价类划分的例子

2.2.1.2 边界值分析

边界值分析法就是对输入或输出的边界值进行测试的方法。这里所说的边界值包含边界值的两边的值。边界值测试的原理是:错误更有可能出现在输入变量的极值附近,基本思想是:在最小值、略高于最小值、正常值、略低于最大值、最大值处取输入变量的值。

在测试边界条件时要遵循以下几个准则:

a.若输入条件规定了取值的范围,则应取刚达到这个范围的边界值,以及刚超过这个范围边界的值作为测试数据;

b.若输入条件规定了取值的个数,则应使用最大个数、最小个数、比最小个数少一个、比最大个数多一个的数作为测试数据;

c.若程序的软件需求规格说明指明输入或输出域是个有序集合,应注意选择有序集的第一个和最后一个元素作为测试用例。

d.分析软件需求规格说明,找出其他可能的边界条件。

2.2.1.3 随机测试

随机测试指测试数据是在所有可能输入值中随机选取的测试数据的方法,是一种基本的黑盒测试方法。随机选取用随机模拟的方法,包括用伪随机数发生器、硬件随机模拟器产生测试数据。测试人员只需规定输入变量的取值区间,在需要时提供必要的变换机制,使产生的随机数服从预期的概率分布。对包括实时软件在内的许多程序,随机测试有较高的效费比。但是,由于测试用例应该包括预期输出结果,对随机测试来说这是比较困难的。这个问题有两个解决方法。一个是对每一组测试数据都用人工方法得出其预期结果,其过程繁琐影响了随机测试的效率。另一个方法是提供一个性质相同的,取一经过验证的程序作为参照,对测试结果进行比较。但是在多数情况下,找到这样一个可供比较的程序比较难。因此,在选用随机测试方法时,要考虑预期的测试结果是否容易得到。

随机测试的缺陷是不能事先将输入存入文档,在排错时无法重现测试中错误发生的过程,也无法进行回归测试。补救的方法是将随机产生的测试数据记录备用。

2.2.2 白盒测试(White-box Testing)

白盒测试作为结构测试方法,是一种按照程序内部逻辑结构和编码结构设计测试数据的测试方法。它会根据代码的组织结构查找软件缺陷,要求测试人员对软件的结构和作用有详细的了解。测试人员利用程序内部的逻辑结构及相关信息设计或选择测试用例。

2.2.2.1 语句覆盖

语句覆盖是指在执行测试用例时,使程序的每条语句都至少执行一次,但要求设计足够多的测试用例,并且语句覆盖并不能发现某些逻辑错误[4]。

如图1所示流程图,要使其达到语句覆盖,只需选取:A=2,B=0,X=3。

但是这个测试还不彻底,如果AND误写成了OR,上面的语句覆盖测试就发现不了。

图1 一个程序的流程图

2.2.2.2 判定覆盖

判定覆盖又称分支覆盖,判定覆盖是执行足够的测试用例,使得程序中每个判定都获得一次“真”或“假”值,或者使每一个分支都至少通过1次覆盖测试策略。

对图1来说,设计两组测试数据就可使它通过路径ace和abd或路径acd和abe达到判定覆盖(见表3)。

表3 判定覆盖测试用例

判定覆盖也有不完全测试的情况,如上面两个测试用例未能测试沿着路径abd执行时,值是否保持不变。

2.2.2.3 条件覆盖

条件覆盖式执行足够的测试用例,使得判定中的每个条件获得各种可能的值的测试策略。

条件覆盖要求设计足够多的测试用例,使得判定中的每个条件获得各种可能的结果。同时每个入口点和出口点至少要唤醒一次。

图1的流程图中,在a点有条件:A>1和B=0,在b点有条件:A=2和X>1,要达到条件覆盖,需要足够多的测试用例,使得在a点有A>1,A≤1,B=0,B≠0,在 b 点有 A=2,A≠2,X >1,X≤1。我们选如表4所示的两组测试输入。

表4 条件覆盖测试用例

由上例可以看出,条件覆盖并不能保证判定覆盖。

2.2.2.4 判定/条件覆盖

判定条件覆盖是执行足够的测试用例,使得判定中的每个条件获得各种可能的值,并使得每个判定取得各种可能的结果的测试策略。

图1的流程图,可用表5所示两组测试输入达到判定/条件覆盖。

表5 判定/条件覆盖测试用例

判定/条件覆盖准则满足判定覆盖准则和条件覆盖准则。判定/条件覆盖准则的缺点是未考虑条件的组合情况。

2.2.2.5 条件组合覆盖

条件组合覆盖是执行足够的测试用例,使得每个判定中的条件的各种组合至少出现1次的测试策略。其特点是覆盖较充分,满足条件组合的覆盖测试用例也一定满足判定覆盖、条件覆盖、判定/条件覆盖。

对图1的流程图,可选用表6的测试输入组合。

表6 多重条件覆盖测试用例

2.2.2.6 更改的判定/条件覆盖(MC/DC)

更改的判定/条件覆盖要求设计足够多的测试用例,使得判定中每个条件的所有可能结果至少出现一次,每个判定本身的所有可能结果也至少出现一次,每个入口点和出口点至少要唤醒一次。并且每个条件都显示能单独影响判定结果[5]。

判断每个条件是否能单独影响判定结果的方法是:在固定其它条件值的同时变化要检查的条件。更改的判定/条件覆盖继承了多重条件覆盖的优点,同时只是线性地增加了测试用例的数量。例:A and B,其全部的条件组合见表7。

表7 A and B全部条件组合测试用例

测试用例1和3说明条件A独立地影响测试结果,测试用例1和2说明条件B独立地影响测试结果,所以测试用例1,2,3是必须的。

3 结束语

软件测试是一个系统性的工作,涉及软件研制的各个阶段,本文所论述的关键技术覆盖整个软件测试的全过程,但是在实际工作中可以根据被测软件的情况,选择采用合适的技术与方法,也可以利用成熟的测试工具进行。在多年的软件测试工作中,笔者利用上述关键技术完成了几十个型号产品上百个软件配置项的测试工作,发现了大量的软件设计缺陷与错误,有效地保证了型号产品的质量与可靠性。

[1] 徐芳主编.软件测试技术[M].北京:机械工业出版社,2006.

[2] 王健编著.软件测试员培训教材[M].北京:电子工业出版社,2003.

[3]贺红卫,杨芳等译.实用软件测试过程[M].北京:机械工业出版社,2004.

[4] 尹党辉,于佳伟,李虎.软件覆盖测试技术研究[J].中国测试,2012,38(z):42-44.

[5]胡江卫,吴伟等.嵌入式软件测试[M].北京:机械工业出版社,2009.

猜你喜欢
测试数据测试用例等价
等价转化
一个点并路的补图的色等价图类
测试用例自动生成技术综述
回归测试中测试用例优化技术研究与探索
基于SmartUnit的安全通信系统单元测试用例自动生成
测试数据管理系统设计与实现
n次自然数幂和的一个等价无穷大
基于自适应粒子群优化算法的测试数据扩增方法
空间co-location挖掘模式在学生体能测试数据中的应用
将问题等价转化一下再解答