580 likes | 721 Views
第二章 软件测试基础. 2.1 软件测试白箱法 2.1.1 逻辑覆盖法 语句覆盖 判断覆盖 条件覆盖 条件组合覆盖 判断 / 条件覆盖 路径覆盖 2.1.2 基本路径测试. 第二章 软件测试基础. 2.2 软件黑箱测试法 2.2.1 等价分类法 2.2.2 边界值分析法 小结. 2.1 软件测试白箱法. 定义: 白箱法是以程序的内部逻辑为依据。合理的白箱测试,就是要选取足够的测试用例,对源代码进行比较充分的覆盖,以便尽可能多地发现程序中的错误。 白箱法适用范围: 主要用于模块测试、 测试 等。 两种方法:
E N D
第二章 软件测试基础 • 2.1 软件测试白箱法 • 2.1.1 逻辑覆盖法 • 语句覆盖 • 判断覆盖 • 条件覆盖 • 条件组合覆盖 • 判断/条件覆盖 • 路径覆盖 • 2.1.2 基本路径测试
第二章 软件测试基础 • 2.2 软件黑箱测试法 • 2.2.1 等价分类法 • 2.2.2 边界值分析法 • 小结
2.1 软件测试白箱法 • 定义: • 白箱法是以程序的内部逻辑为依据。合理的白箱测试,就是要选取足够的测试用例,对源代码进行比较充分的覆盖,以便尽可能多地发现程序中的错误。 • 白箱法适用范围: • 主要用于模块测试、测试等。 • 两种方法: • 逻辑覆盖法和基本路径法两种。
(A>1)∧(B=0) (A=2)∨(X>1) a T c F b X=X/A T e X=X+1 F d 2-1 一个被测程序结构图 2.1.1 逻辑覆盖法
2.1.1 逻辑覆盖法 • 语句覆盖: • 语句覆盖的含义是指在测试的过程中,软件测试者应选择足够多的测试用例,使被测试程序中每个语句至少执行一次。 • 例子: • 在图2-1所示的流程图中,正好所有的可执行语句都在路径L1上,故选择路径L1设计测试用例,就可以覆盖所有的可执行语句。满足本例的测试用例是:[(2,0,4),(2,0,3)]覆盖ace[L1]。
问题: • 本测试用例实际上只测试了条件为真的情况,如果条件为假,则使用本测试用例显然不能发现问题。此外,当第一个判断中的逻辑符“”写成“”,或者第二个判断中的逻辑符号“” 写成“”时,本测试用例也不能查出上述错误。所以,语句覆盖是最弱的逻辑覆盖准则。
判断覆盖: • 在测试的过程中,软件测试者应设计若干测试用例,并运行所测程序,使被测试程序中每个判断的真分支和假分支至少经历一次。 • 例如 • 在图2-1所示的流程图中,如果选择路径L1,L2,则可满足判断覆盖,其测试用例如下: • [(2,0,4),(2,0,3)]覆盖ace[L1] • [(1,1,1),(1,1,1)]覆盖abd[L2]。 • 如果选择路径L3和L4,则可得另一组测试用例: • [(2,1,1),(2,1,2)]覆盖abe[L3] • [(3,0,3),(3,1,1)]覆盖acd[L4]。
问题: • 由此看来,测试用例的取法并不是唯一的。此外,若把图2-1所示流程中的第二个判断中的条件X>1错些成X<1,那么利用上面两组测试用例,仍能得到同样的结果。这表明:只是判断覆盖不能确保一定能查出在判断的条件中存在的错误。
条件覆盖: • 用条件覆盖所设计的测试用例可使得程序中的每一个判断的每一个条件的可能取值至少执行一次。 • 例如: • 在图2-1所示的流程中,事先可对所有条件的取值加以标注,比如: • 对第一个判断,若条件A>1成立,则取真值为T1,反之,取假值为~T1;若条件B=0成立,则取真值为T2,反之,取假值为~T2。 • 对第二个判断,若条件A=2成立,则取真值为T3,反之,取假值为~T3;若条件X>1成立,则取真值为T4,反之,取假值为~T4。
问题: • 比较这两组测试用例可以发现,第一组测试用例不仅覆盖了所有判断的取真分支和取假分支,而且覆盖了判断中条件的可能取值;第二组测试用例虽然满足了条件覆盖,但由于只覆盖了第一个判断的取假分支和第二个判断的取真分支,不满足判定覆盖的要求。为此,必须引入更强的覆盖,即判定-条件覆盖。
判断-条件覆盖: • 用判断-条件覆盖所设计的测试用例能够使得判断中每一个条件的所有可能取值至少执行一次,同时每个判断的所有可能判断结果至少执行一次。 • 例如:
问题: • 从表面上看,它测试了所有条件的取值,但事实并非如此。这是由某些条件覆盖了另一些条件所致,比如对于条件表达式(A>1)and (B=0)来说,若(A>1)的测试结果为真,则还要测试(B=0),才能决定表达式的值;而若(A>1)的测试结果为假,可以立刻确定表达式的结果为假。这时,往往就不再测试(B=0)的取值了,因此,条件(B=0)就没有检查。同样,对于条件表达式(A=2)or (X>1)来说,若(A=2)的测试结果为真,就可以立刻确定表达式的结果为真。这时,条件(X>1)就没有检查。因此,采用判断-条件覆盖,也不一定能查出逻辑表达式中的错误。
条件组合覆盖 • 能够使得每个判断的所有可能的条件取值组合至少执行一次。 • 测试用例:
问题: • 这里并未要求第一个判断的4个组和与第二个判断的4个组和再进行组合。要是那样的话,就需要24=16个测试用例。
路径测试: • 路径测试就是设计足够的测试用例,覆盖程序中所有可能的路径。 • 测试用例:
测试用例逻辑分析法 L1(a→c→e) ={(A>1) and (B=0)} and {(A=2) or (X/A>1)} =(A>1) and (B=0) and (A=2) or (A>1) and (B=0) and (X/A>1) =(A=2) and (B=0) or (A>1) and B=0 and (X/A>1) L2(a→b→d) ={(A>1) and (B=0)} and {(A=2) or (X>1)} ={(A>1) or (B=0)} and {(A=2) and (X>1)} =(A<=1) and (X<=1) or (B<>0) and (A<>2) and (X<=1)
L3(a→b→e) ={(A>1) and (B=0)} and {(A=2) or (X>1)} ={(A>1) or (B=0)} and {(A=2) or (X>1)} =(A<=1) and (X>1) or (B<>0) and (A=2) or (B<>0) and (X>1) L4(a→c→d) ={(A>1) and (B=0)} and {(A=2) or (X/A>1)} =(A>1) and (B=0) and (A<>2) and (X/A<=1)
2.1.2 基本路径测试法 • 基本思路: • 基本路径测试方法允许测试用例设计者导出一个过程设计的逻辑复杂性侧度,并使用该侧度作为指南来定义执行路径的基本集。从该基本集导出的测试用例保证对程序中的每一条语句至少执行一次。 • 流图符号
顺序语句 While语句 Unit语句 If 语句 图 2-3 流图符号 Case语句
流图定义: • 每一个圆称为流图的节点,代表一个或多个语句。一个处理方框序列和一个菱形决策框可被映射为一个节点。流图中的箭头,称为边或连接,代表控制流,类似于流程图中的箭头。一条边必须终止于一个节点,即使该节点并不代表任何语句。由边和节点限定的范围称为区域。计算区域时应包括图外部的范围。
2 4 7 8 5 9 10 图2-4(a) 1 3 6
1 6 2.3 9 10 8 11 7 4.5 R2 R3 R1 R4 图2-4(b)
环形复杂性 • 独立路径是指程序中至少引进一个新的处理语句集合或一个新条件的任一路径。采用流图的术语,即独立路径必须至少包含一条在定义路径之前不曾用到的边。
例如: • 路径1:1-11 • 路径2:1-2-3-4-5-10-1-11 • 路径3:1-2-3-6-8-9-10-1-11 • 路径4:1-2-3-6-7-9-10-1-11 • 注意: • 每一条新的路径都包含了一条新边。路径1-2-3-4-5-10-1-2-3-6-8-9-10-1-11不是独立路径,意味它只是已有路径的简单合并,并未包含任何新边。应该注意到基本集并不唯一。实际上,给定的过程设计可派生出任意数量的不同基本集。
环形复杂性的定义与算法: • 流图中区域的数量对应于环形的复杂性 • 给定流图G的环形复杂性V(G),定义为V(G)=E-N+2,E是流图中边的数量,N是流图节点数量。 • 给定流图G的环形复杂性V(G),也可定义为V(G)=P+1,P是流图G中判定节点的数量。
3 1 4 2 7a 7b 5 8 6 PDL Procedure sort 1:Do while records remain Read record; 2: If record field1=0 3: Then process record; Store in buffer; Increment counter 4: elseif record field2=0 5: then reset counter; 6: else process record; store in file; 7a: endif endif 7b:enddo 8end 图2-5将PDL翻译成流图 例子:
基本路径法步骤: • 步骤1:以设计或代码为基础,画出相应的流图。 • 步骤2:确定结果流图的环形复杂性。可采用上一节的任意一种算法来计算环形复杂性V(G)。应该注意到,计算V(G)并不一定要画出流图,计算PDL中的所有条件语句数量(过程求平均值中复合条件语句计数为2),然后加1即可得到环形复杂性。
步骤3:确定线性独立的路径的一个基本集。 • 步骤4:准备测试用例,强制执行基本集中每条路径。测试人员可选择数据以便在测试每条路径时适当设置判定结点的条件。
Procedure average;//计算不超过100个数字的平均值;同时计算总和与有效数字个数 INTERFACE RETURNS average.total.input.total.valid; INTERFACE ACCEPTS value,minimum,maximum; Type value[1:100] IS SCALAR ARRAY; TYPE average,total.input,total.valid Minimum, maxImun, sum IS SCALAR TYPE I IS INTEGER; I=1;Sum=0; 1) Total.input=total.valid=0; DO WHILE value[i]<>-999 and total.input<100 4) Increment total.input by 1; 5) IF value[i]>=minimum AND value[i] <=maximum 7) THEN increment total.valid by1; Sum=sum+valid[i] ELSE skip 8) ENDIF Increment I by 1; 9) ENDDO IF total.valid>0 11) THEN average=sum/total.valid; 12) ELSE average=-999; 13)ENDIF END average 2 3 6 10 图2-7 测试用例设计的PDL,其节点已经标识
1 2 3 4 5 6 7 9 8 13 11 12 10 图2-8 过程求平均值的流图
在过程求平均值中,有6条路经: • 路径1:1-2-10-11-13 • 路径2:1-2-10-12-13 • 路径3:1-2-3-10-11-13 • 路径4:1-2-3-4-5-8-9-2-… • 路径5:1-2-3-4-5-6-8-9-2-…. • 路径6:1-2-3-4-5-6-7-8-9-2-… • 路径4、5和6后面的省略号(……)表示可以加上控制结构其余部分的任意路径。
路径1测试用例(1-2-10-11-13): • value(k) = 有效输入,其中k < i • value(i) = -999, 其中2≤i≤100 • 期望结果:基于k的正确平均值和总数。 • 注意:路径1无法独立测试,必须作为路径4、5和6测试的一部分。 • 路径2测试用例(1-2-10-12-13) : • value(1) =-999 • 期望结果:平均值=-999;其它按初值汇总。
路径3测试用例 (1-2-3-10-11-13): • 试图处理101或更大的值 • 前100个数值应该有效 • 期望结果:与测试用例1相同 • 路径4测试用例 (1-2-3-4-5-8-9-2): • value(k) <最小值 • value(i) =有效输入,其中i≤100 • 期望结果:基于k的正确平均值和总数。
路径5测试用例(1-2-3-4-5-6-8-9-2) : • value(k) >最大值 • value(i) = 有效输入,其中I<100 • 期望结果:基于k的正确平均值和总数。 • 路径6测试用例(1-2-3-4-5-6-7-8-9-2) : • value(i) =有效输入,其中I<100。 • 期望结果:基于k的正确平均值和总数。
图矩阵 : • 图矩阵是一个正方形矩阵,其大小(即行数和列数)等于流图的节点数。每列和每行都对应于标识的节点,矩阵项对应于节点间的连接(边),图2-9显示了一个简单的流图及其对应的图矩阵。
1 5 3 4 2 a b e d f c g 图2-9 连接矩阵
连接矩阵: • 对每一个矩阵项加入连接权值,图矩阵就可以用于在测试中评估程序的控制结构,连接权值为控制流提供了另外的信息。最简单情况下,连接权值是1(存在连接)或0(不存在连接)。 • 连接权值可以赋予更有趣的属性: • 穿越连接的处理时间 • 穿越连接时所需的内存 • 执行连接的概率 • 穿越连接所需的资源
2.2 软件测试黑箱法 • 黑箱法定义: • 黑箱法以程序的功能作为测试依据的测试方法。一个黑箱测试就是选择足够多的测试用例,检验所有软件的输入。 • 黑箱测试用于发现以下类型的错误: • 功能不符合要求或遗漏; • 界面错误; • 数据结构或外部数据库访问错误; • 性能偏差; • 初始化或终止错误;
测试用例回答下例问题: • 如何测试功能的有效性? • 何种类型的输入会产生好的测试用例? • 系统是否对特定的输入值敏感? • 如何分隔数据类的边界? • 系统能够承受何种数据率和数据量? • 特定类型的数据组合会对系统产生何种影响?
标准的测试用例集: • 所设计的测试用例能够减少达到合理测试所需的附加测试用例数;(最小测试) • 所设计的测试用例能够告知某些类型错误的存在与不存在,而不仅仅是告知与特定测试相关的错误。
2.2.1 等价分类法 • 定义: • 等价类划分是一种黑箱测试方法。它是将程序的输入域划分为数据类,以便导出测试用例。理想的测试用例是能用一个用例可以发现一类错误。 • 依据: • 如果将某个等价类的一个输入条件作为测试数据进行测试并查出了错误,那么使用这一等价类中的其他输入条件进行测试也会查出同样的错误;反之,若使用某个等价类中的一个输入条件作为测试数据进行测试没有查出错误,则使用这个等价类中的其它输入条件也同样查不出错误。
等价类划分要考虑以下两种情况: • 有效等价类。对于程序的规格说明来说,有效等价类是合理的、有意义的输入数据构成的集合。利用它可以检验程序是否实现了规格说明预先规定的功能和性能。 • 无效等价类。对于程序的规格说明来说,无效等价类是不合理的、无意义的输入数据构成的集合。这一类测试用例主要用于检测程序中的功能和性能是否有不符合规格说明要求。
(1)确定有效等价类 • 确定等价类的原则1: • 如果输入条件中规定了取值范围或值的个数,则可以确立一个有效等价类和两个无效等价类。例如,在程序的规格说明中,若对输入条件有一个规定: “…项数可以从1到999…” 则有效等价类是“1<=项数<=999”,两个无效等价类是“项数<1”或“项数>999”
原则2: • 如果输入条件中规定了输入值的集合,或者是规定了“必须如何…”的条件,则可确立一个有效等价类和一个无效等价类。例如,若在pascal语言中对变量标识符规定为“以字母打头的…串”,那么所有以字母打头的构成有效等价类,而不以字母打头的归于无效等价类。
原则3: • 如果输入条件是一个布尔量,则可以确定一个有效等价类和一个无效等价类。 • 原则4: • 如果规定了输入数据的一组值,而且程序要对每个输入值分别进行处理,则可以每个输入值确定一个有效等价类,并针对这组值确立一个无效等价类,即所有不允许的输入值的集合。
原则5: • 如果给定了输入数据必须遵守的规则,则可以确立一个有效等价类(符合规则)和若干个无效等价类(从不同角度违反规则)。例如,pascal语言规定“一个语句必须以分号‘;’结束”,据此就可以确定一个有效等价类“以‘;’结束”,若干个无效等价类“以‘;’结束”、“以‘,’结束”、“以‘’结束”、“以LF结束”等等。
原则6: • 如果确知已经划分的等价类中各元素在程序中的处理方式不同,则应将此等价类进一步划分成更小的等价类。
(2)确立测试用例 • 从等价类中按以下原则选择测试用例: • 为每一个等价类规定一个唯一的编号; • 设计一个新的测试用例,使其尽可能多地覆盖尚未被覆盖的有效等价类,重复这一步,直到所有的有效等价类都被覆盖为止。 • 设计一个新的测试用例,使其仅覆盖一个尚未被覆盖的无效等价类,重复这一步,直到所有的无效等价类都被覆盖为止。之所以要这样做,是因为在某些程序中对某一输入错误的检查往往会屏蔽对其它输入错误的检查。因此必须针对每一个无效等价类,分别设计测试用例。