软件工程黑盒白盒测试

2021-01-14 10:31:18 浏览数 (1)

目的是为了应付期末考试,期末考试肯定会考测试的习题。

一、概述

先总览一下测试的分类:

重点掌握黑盒测试和白盒测试。

黑盒由白盒的区别:

黑盒测试

  • 检查程序各功能是否能实现,检查功能错误;
  • 黑盒测试与软件的具体实现过程无关,只关心结果;
  • 所以又被称为功能测试。

白盒测试

  • 检查内部操作是否按规定执行,各功能是否得到充分的使用;
  • 所以又被称为结构测试。

二、黑盒测试方法

有很多种方法,这里主要讲解两种比较常用常考的方法,分别是等价类划分、边界值分析。

2.1 等价类划分

先来一个引例: NextDate 函数问题:

  • 是有三个变量 monthdayyear 的函数;
  • 输出为输入日期后一天的日期。

例如:输入为1986年6月9日,则该函数的输出应为1986年6月10日。

这个问题涉及到闰年的问题,因为闰年的日期是不一样的。


等价类划分法是把程序的 输入域 划分为若干部分,然后从每个部分中选取少数代表性数据当作测试用例。

引例中的输入域可以分为:年、月、日。

划分等价类可分为两种情况:

  1. 有效等价类:是指有意义的、合理的输入数据所组成的集合。
  2. 无效等价类:是指无意义的、不合理的输入数据所构成的集合。

在确立了等价类之后,建立 等价类表 ,列出所有划分出的等价类。

然后设计测试用例:

  • 首先为等价类表中的每一个等价类分别规定一个唯一的编号;
  • 设计一个新的测试用例,使它能够尽量覆盖尚未覆盖的有效等价类。
  • 重复这个步骤,直到所有的有效等价类均被测试用例所覆盖。
  • 设计一个新的测试用例,使它仅覆盖一个尚未覆盖的无效等价类。
  • 重复这一步骤,直到所有的无效等价类均被测试用例所覆盖。

现在我们总结一下等价类划分法的步骤:

  1. 确定输入域;
  2. 划分等价类;
  3. 建立 等价类表
  4. 对等价类进行 编号
  5. 设计测试用例覆盖所有的等价类。

下面给一个例子,我们使用总结的方法完成这道题目。

例题:某“调整工资”处理模块接受一个“职称”的变量,根据职称的不同(助教,讲师,副教授,教授)作不同的处理,其中若是助教还必须输入工龄,只有工龄超过两年才能调整工资。请用 等价类划分法 设计测试用例 。

首先确定输入域:用户可以输入职称、职称兼工龄。

划分等价类,等价类分为合理等价类和不合理等价类:合理等价类为教授、副教授、讲师、助教并且工龄大于2年。

建立等价类表并进行编号:

设计可以覆盖所有等价类的测试用例:

2.2 边界值分析

边界值分析法就是对输入或输出的边界值进行测试的一种黑盒测试方法。

步骤如下:

  1. 首先确定边界情况;
  2. 选取正好等于、刚刚大于或刚刚小于边界的值作为测试数据。

举个例子:测试计算平方根的函数。

代码语言:javascript复制
——输入:实数
——输出:实数
——规格说明:
       当输入一个 0 或比 0 大的数的时候,返回其正平方根;
       当输入一个小于 0 的数时,显示错误信息“平方根非法-输入值小于 0 ”并返回 0 ;
       库函数 Print-Line 可以用来输出错误信息。

等价类划分:

代码语言:javascript复制
输入 (i) < 0 和 (ii) >= 0
输出 (a) >= 0 和 (b) Error 

测试用例:

代码语言:javascript复制
输入 4 ,输出 2 。对应于 (ii) 和 (a) 。
输入 -10 ,输出错误提示。对应于 (i) 和 (b) 。
代码语言:javascript复制
边界值分析:划分 (ii) 的边界为 0 和最大正实数;
划分 (i) 的边界为最小负实数和 0 。
由此得到以下测试用例:
	 输入 {最小负实数}
	 输入 {绝对值很小的负数}
	 输入 0
	 输入 {绝对值很小的正数}
	 输入 {最大正实数}

例1:有二元函数 f(x,y),其中 x∈[1,12]y∈[1,31]

采用边界值分析法设计的测试用例是:

代码语言:javascript复制
{ <1,15>, <2,15>, <11,15>, <12,15>, <6,15>, <6,1>, <6,2>, <6,30>, <6,31> }

推论:对于一个含有 n 个变量的程序,采用边界值分析法测试程序会产生 4n 1 个测试用例。

例二:有函数 f(x,y,z) ,其中 x∈[1900,2100]y∈[1,12]z∈[1,31]

采用边界值分析法设计的测试用例是:

代码语言:javascript复制
{
<2000,6,1>, <2000,6,2>, <2000,6,30>, <2000,6,31>,
<2000,1,15>, <2000,2,15>, <2000,11,15>, <2000,12,15>,
<1900,6,15>, <1901,6,15>, <2099,6,15>, <2100,6,15>, 
<2000,6,15>
} 

三、白盒测试方法

白盒测试用到控制流图:控制流图(可简称流图)是对程序流程图进行简化后得到的,它可以更加突出的表示过程控制流的结构。

主要使用到两种图形符号:节点和控制流线。

流程图都可以转化为控制流图:

下面介绍逻辑覆盖测试方法,也是常考的内容,要掌握。

逻辑覆盖测试方法分为:

  • 语句覆盖;
  • 判定覆盖;
  • 条件覆盖;
  • 判定/条件覆盖;
  • 组合覆盖;
  • 路径覆盖。

例如:程序

代码语言:javascript复制
If(A > 1 && B = 0)
   X = X / A;
If(A = 2 || X > 1)
   X = X   1;
代码语言:javascript复制
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 )
= not {(A>1) and (B=0)} and  not {(A=2) or (X>1)}
= { not (A>1) or not (B=0) } and { not (A=2) and not (X>1) }
= not (A>1) and not (A=2) and not (X>1) or not (B=0) and not (A=2) and not (X>1)
= not (A>1) and not (X>1) or not (B=0) and not (A=2) and not (X>1)

L3 ( a → b → e)
= not {(A>1) and (B=0)} and {(A=2) or (X>1)}
= { not (A>1) or not (B=0)} and {(A=2) or (X>1)}
= not (A>1) and (A=2) or not (A>1) and (X>1) or not (B=0) and (A=2) or not (B=0) and (X>1)

L4 ( a → c → d )
= {(A>1) and (B=0)} and not {(A=2) or (X/A>1)}
= (A>1) and (B=0) and not (A=2) and not (X/A>1)

3.1 语句覆盖

语句覆盖就是设计足够多个测试用例,运行被测程序,使得每一可执行语句至少执行一次。

在图例中,正好所有的 可执行语句 都在路径 L1 上,所以选择路径 L1 设计测试用例,就可以覆盖所有的可执行语句。

3.2 判定覆盖(分支覆盖)

判定覆盖就是设计若干个测试用例,运行被测程序,使得程序中 每个判断的取真分支和取假分支 至少经历一次。

代码语言:javascript复制
对于图例,如果选择路径 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, 0, 1)】覆盖 acd【L4】

3.3 条件覆盖

条件覆盖就是设计若干个测试用例,运行被测程序,使得程序中每个判断的 每个条件的可能取值 至少执行一次。

在图例中,我们事先可对所有条件的取值加以标记。例如:

对于第一个判断:

  • 条件 A>1 取真为 T1,取假为F1;
  • 条件 B=0 取真为 T2,取假为 F2;

对于第二个判断:

  • 条件 A=2 取真为 T3,取假为条件F3;
  • X>1 取真为 T4,取假为 F4
代码语言:javascript复制
测试用例           		   覆盖分支    		  条件取值
【(2, 0, 4),(2, 0, 3)】    L1(c, e)  		T1 T2 T3 T4
【(1, 0, 1),(1, 0, 1)】    L2(b, d)  		F1 T2 F3 F4
【(2, 1, 1),(2, 1, 2)】    L3(b, e)			T1 F2 T3 F4

或者:
【(1, 0, 3),(1, 0, 4)】    L3(b, e) 			F1 T2 F3 T4
【(2, 1, 1),(2, 1, 2)】    L3(b, e) 			T1 F2 T3 F4

3.4 判定/条件覆盖

设计足够多的测试用例,使得程序中 每个判定包含的每个条件的所有情况 (真/假)至少出现一次,并且 每个判定本身 的判定结果(真/假)也至少出现一次。

满足判定/条件覆盖的测试用例一定同时满足判定覆盖和条件覆盖。

代码语言:javascript复制
测试用例           		   覆盖分支    		  条件取值
【(2, 0, 4),(2, 0, 3)】    L1(c, e)  		T1 T2 T3 T4
【(1, 1, 1),(1, 1, 1)】    L2(b, d)  		F1 F2 F3 F4

3.5 组合覆盖

通过执行足够的测试用例,使得程序中 每个判定的所有可能的条件取值组合 都至少出现一次。

满足组合覆盖的测试用例一定满足判定覆盖、条件覆盖和判定/条件覆盖。

代码语言:javascript复制
1、A>1,B=0  作 T1 T2
2、A>1,B≠0  作 T1 F2
3、A≯1,B=0  作 F1 T2
4、A≯1,B≠0  作 F1 F2
5、A=2,X>1  作 T1 T3
6、A=2,X≯1  作 T1 F3
7、A≠2,X>1  作 F1 T3
8、A≠2,X≯1  作 F1 F3
代码语言:javascript复制
测试用例          			覆盖条件     				覆盖组合
【(2, 0, 4),  (2, 0, 3)】    (L1)	    	            1, 5
【(2, 1, 1),  (2, 1, 2)】    (L3)	    	            2, 6
【(1, 0, 3),  (1, 0, 4)】    (L3)	    	            3, 7
【(1, 1, 1),  (1, 1, 1)】    (L2)	    	            4, 8

就相当于是排列组合中的那个组合,把所有的情况都罗列出来。

3.6 路径覆盖

设计足够多的测试用例,要求覆盖程序中所有可能的路径。 从流程图和控制流图上可以看出,其中有 4 条可能的路径,分别是L1L2L3L4

0 人点赞