购买
下载掌阅APP,畅读海量书库
立即打开
畅读海量书库
扫码下载掌阅APP

5.4 循环结构覆盖

5.4.1 循环结构

循环结构(Loop Structure)是为了在一定条件下,反复执行某项功能而设计的一种程序结构。一个循环结构由循环变量、循环体及循环终止条件构成。不同编程语言具有不同的循环类型。C语言包括for、while、do while共3种类型的循环结构。

for循环是当型循环(when type loop),在循环体执行前进行条件判断,当条件满足时,进入循环,否则结束循环。其格式为

for(表达式1;表达式2;表达式3)语句:/*循环体*/

图5-18展示了for-next循环的结构及执行过程。

图5-18 for-next循环结构及执行过程

while循环同样也是当型循环。通常,在不知道循环次数的情况下,使用while循环。在while循环结构中,维持循环的是一个条件表达式,语句是循环体,当表达式为真时,执行循环体内语句,否则终止循环,执行循环体外语句。

do…while循环是直到型循环(until type loop),在循环次数未知的情况下,使用do…while循环,它和while循环的区别在于do…while循环结构是当执行完一遍循环体之后,再进行条件判断。

5.4.2 循环结构测试

循环结构测试是一种特殊的路径测试,旨在验证循环结构的有效性。而对于不同的循环结构,循环次数通常不确定且可能很大,所包含的执行路径数可能非常庞大,难以或无法对循环结构进行路径穷举。

循环结构分为简单、串接、嵌套和不规则共4种循环结构。不规则循环结构由简单、串接、嵌套循环结构组合而成,通常需要将其转化成简单、串接、嵌套结构之后方可测试。图5-19给出了简单、串接、嵌套3种基本循环结构。

图5-19 简单、串接、嵌套循环结构

5.4.2.1 简单循环

对于简单循环结构,测试内容包括循环变量的初值、最大值、增量是否正确以及何时退出循环等4个方面。假设简单循环结构的最大循环次数为 n ,可以采用如下策略进行测试设计:

(1)跳过整个循环。

(2)只循环一次。

(3)只循环两次。

(4)循环 m 次, m < n

(5)分别循环 n −1 、 n n +1 次。

这里,我们考察如下简单循环结构。

上述程序定义了两个整型变量i和sum,输入i,当i<=10时,执行循环。sum的值每次加1,i自身加1,最后输出sum的值。对此,即可使用表5-18给出的测试项,进行测试设计。

表5-18 简单循环结构测试项

5.4.2.2 串接循环

串接循环将不同循环结构串接在一起,如果各循环体彼此独立,可以使用简单循环结构的测试方法实现串接循环结构测试,但如果循环体彼此不独立,则可以分别使用简单循环的测试方法对每个循环结构进行测试。如果两个循环串接,且第一个循环的循环计数器值是第二个循环的初始值,则表明这两个循环相互关联。当串接循环不独立时,通常使用嵌套循环测试方法实现串接循环结构测试。

5.4.2.3 嵌套循环

将简单循环结构的测试方法用于嵌套循环,可能的测试次数会随着嵌套层数增加而呈几何级数增加。通常,采用如下方法来减少测试次数:

(1)从最内层循环开始,所有外层循环次数设置为最小值。

(2)对最内层循环按照简单循环的测试方法完成测试。

(3)由内向外进行下一个循环测试,本层循环的所有外层循环仍取最小值,而由本层循环嵌套的循环取某些典型值。

(4)重复上一步的过程,直到所有循环测试完毕。

工程上,对于嵌套循环结构,应重点测试如下几个方面:

(1)当外层循环变量为最小值,内层循环变量也为最小值时的运算结果。

(2)当外层循环变量为最小值,内层循环变量为最大值时的运算结果。

(3)当外层循环变量为最大值,内层循环变量为最小值时的运算结果。

(4)当外层循环变量为最大值,内层循环变量也为最大值时的运算结果。

(5)循环变量的增量是否正确。

(6)何时退出内层循环,何时退出外层循环。

这里,考察如下嵌套循环结构。

该程序定义了一个二维整型数组a[5][5]及两个循环变量i和j,通过一个嵌套循环对数组的每个元素赋值,即将元素所在的行和列相加并输出。对此,使用如表5-19所示嵌套循环结构测试项,进行测试设计。

表5-19 嵌套循环结构测试项

5.4.3 Z路径覆盖下的循环测试

Z路径覆盖是路径覆盖的一个变体。对于较简单程序,路径覆盖非常简单。当程序中出现多个判断或多个/多种循环时,路径数可能非常庞大,全数路径覆盖非常困难,也不现实。为了解决这一问题,必须舍弃一些次要因素,对循环机制进行简化,最大限度地减少路径数量,使得覆盖有限路径成为可能。称简化循环意义下的路径覆盖为Z路径覆盖。无论循环形式还是循环体实际执行的次数,简化后的循环测试只考虑执行循环体1次和0次,即考虑执行时进入循环体1次和跳过循环体这两种情况。图5-20给出了循环简化的基本方法。

图5-20 循环简化的基本方法

路径可以用路径树来表示。当得到某一路径的路径树之后,从根节点开始,一次遍历,再回到根节点时,将所经历的叶节点排列起来,得到一条路径。如果遍历了所有叶节点,即得到所有路径;当得到所有路径之后,生成每条路径的测试用例,就可以实现Z路径覆盖。

5.4.4 最少测试用例数估算

对于循环结构覆盖,可能需要大量测试用例。而对于某个特定实现,至少需要多少测试用例呢?这需要对最少测试用例数进行估算。结构化程序由顺序型(串行操作)、选择型(分支操作)和重复型(循环操作)3种基本控制结构组成。为简化问题,避免出现测试用例数量巨大而导致组合爆炸,将构成循环操作的重复型结构用选择结构代替。这样,任一循环便可以改造为进入循环体或不进入循环体的分支操作。

N-S(Nassi Shneiderman)图是结构化编程中的一种可视化建模,是流程图的同构,它将流程图中的流程线去掉,将算法置入一个矩形阵内,表示程序的3种基本控制结构。任何N-S图都可以转化为流程图,同时大部分流程图也可以转化为N-S图。4种控制结构的N-S图如图5-21所示。

图中,A、B、C、D、S表示要执行的操作,P是可取真值、假值的谓词,Y表示真值,N代表假值。简化循环假设之后,对于一般控制流,只考虑选择型结构。图5-22表示两个顺序执行分支结构的N-S图。当两个分支谓词P1和P2取不同值时,将分别执行a或b及c或d操作。

图5-21 4种控制结构的N-S图

图5-22 两个顺序执行分支结构的N-S图

显然,至少需要设计4组测试用例才能覆盖该程序逻辑,使得ac、ad、bc、bd操作均得到测试验证。由图5-22可见,第一个分支谓词引出两个操作,第二个分支谓词同样引出两个操作。因此,得到2×2=4 组操作组合,需要设计4组测试用例。这里的2是由两个并列的操作即1+1=2 得到。

对于更加复杂的问题,最少测试用例估算原则同样如此。如果N-S图中存在上下并列的层次A1、A2,那么A1和A2的最少测试用例个数分别是 a 1 和 a 2 ,则由A1、A2两层所组合的N-S图对应的最少测试用例数为 a a 2 ;如果N-S图中不存在并排层次,则对应的最少测试用例数由并排的操作数决定,即N-S图中除谓词之外的操作框的个数。

那么,图5-23所示的两个N-S图,至少需要多少个测试用例来实现逻辑覆盖呢?

图5-23 N-S图示例

对于图5-23(a)所示N-S图,由于图中并不存在并列的层次,最少测试用例数由并排的操作数决定,即为1+1+1=3 。对于图5-23(b)所示N-S图,由于图中没有包含并列的层次,最少测试用例数仍由并排的操作数决定,即为1+1+1+1+1=5 。 XaCUOFViPBfzsVawAHrfmzTt54m/Eiwk/cFHt+AnGRq66NkdPvgM43V140XPkgs1

点击中间区域
呼出菜单
上一章
目录
下一章
×