第五章 系统测试
主要内容,系统测试至少占据了制作过程的一
半工作量,是成功地开发信息系统的重要保证
之一。本章将对系统测试的方法和技术做一系
统地介绍。
5.1 系统测试概述
? 很多人认为, 测试是证明程序中不存在错误的
过程,,, 程序测试的目的是要证明程序正确
地执行了预期的功能,,, 程序测试的过程是
使人们确信程序可完成预期要完成的工作过
程, 。但却是错误的定义。 测试的定义应该是:
为了发现错误而执行程序的过程。从这个定义
出发可以看出应该把查出了 新错误 的测试看作
是成功的测试,没有发现错误的测试则是失败
的测试。
5.1.1 测试的基本方法
? 黑盒测试( Black_Box testing)
– 测试者把程序看成是一个黑盒,完全不考虑
程序内部结构和内部特性而进行的测试
? 白盒测试( White_Box testing)
– 允许人们检查程序的内部结构,是测试者从
检查程序的逻辑着手,得出测试数据,进行
测试的过程
5.1.2 测试的基本原则
? 1、确定预期输出(或结果)是测试数据准备必不可少
的一部分
? 2、程序员应避免测试自己的程序
? 3、程序设计机构不应测试自己的程序
? 4、彻底检查每个测试结果
? 5、对非法的和非预期的输入情况,也要像对合法的、
预期的输入一样,编写测试数据
? 6、检查程序是否做了要做的事仅是成功的一半,另一
半是看程序是否做了不要它做的事
? 7、一定不要扔掉测试数据
? 8、在进行测试设计时不要设想程序中不会查出错误
5.1.3 测试的基本手段
? 人工测试
– 程序审查会
– 人工运行
? 计算机测试
测试所要遵循的步骤,
?1、设计测试数据
?2、进行模块测试
?3、进行高级测试
测试模型:
应用需求
逻辑结构设计
系统外部规范设计
程序结构设计
编写代码
系统分析
阶段
系统设计
阶段
程序设计
调试代码
子模块测试
模块整体测试
功能测试
系统测试
验收测试
高级测试
安装测试
模块测试
5.2 人工测试
? 5.2.1 程序审查会
– 程序审查会( Code Inspections) 是让小组成员阅读程
序代码而进行的一系列步骤和查找错误的办法。
? 组成:
– 由四人组成,其中一个是 调解人,调解人一般由能力
强的程序员担任,但他并不是被检查程序的作者,也
无需熟悉该程序的细节。调解人负责为审查会分发材
料,安排并主持会议,记录所有已查出的错误,并保
证这些错误随之得以改正。所以可以把调解人比做质
量检查工程师。小组的第二个成员就是 程序员,他是
被审查程序的作者,另外两个成员一个是 系统分析或
设计人员,另一个是 测试专家 。系统分析员或设计员
负责对程序的结果进行评审,测试专家负责对整个测
试过程和结果进行评审。
程序审查会的工作过程是,
? 会前准备:
– 调解人在会议开发之前(前几天),把这个
程序清单和设计规范分发给小组的其他成员
? 会议任务:
– 1、请程序员逐个语句地讲述程序的逻辑结
构。期间大家提出问题加以追究,以断定错
误是否存在。
– 2、根据常见程序错误检验单分析程序。
? 会期:
– 90分钟至 120分钟之间
注意的问题:
? 如果程序员把审查会看成是对他的人格的攻击,
从而采取自卫的态度,那么审查过程就会没有
什么效果。反之,程序员一定要抱虚心的态度
参加会议,用正确的和建设性的眼光看待审查
处理,即审查会的目的在于发现程序中的错误,
从而改进他的工作质量。基于这种原因,审查
会的结果应该只限于与会者知道。如果部门或
组织的经理使用了审查会的结果,那么这种审
查过程马上就会失去意义。
检验单包含的经常出现的软件错误:
? 数据引用错误
? 数据说明错误
? 计算错误
? 比较错误
? 控制流程错误
? 接口错误
? 输入 /输出错误
? 其它检查
? ……
5.2.2 人工运行
? 人工运行要求与会者当, 计算机, 。被指定为
测试员的人要携带一组写在纸上的测试数据来
参加会议,这些测试数据都是这个程序或模块
的输入情况及期望的输出中的典型代表。在会
议期间,要人动脑筋运行每一个测试数据。沿
着程序逻辑把这些测试数据走一遍,在纸上或
黑板上监视追踪程序的状态。
? 组成:
– 由三至五人组成。其中一人起类似于程序审查会中
调解人的作用;另外由一人当秘书,他负责记录发
现的错误;第三个人进行测试,称他为测试员。其
他人员可以是一个具有丰富实践经验的程序员、一
个程序语言专家、一个新程序员(以便提供新鲜的
无偏见的意见)、最终将维护这个程序的人、从事
别的项目的人或者是程序小组中的另外一个程序员。
? 会前准备:
– 提前几天提供资料以便仔细研究程序
? 会议内容:
– 与会者当, 计算机,, 运行每一个测试数据。沿着
程序逻辑把这些测试数据走一遍,并监视追踪程序
的状态。
? 会期:
– 持续 1至 2小时而不间断的会议
注意的问题:
? 像程序审查会一样,与会者的态度极其重要。
与会者应该评论程序而不是评论程序员。不能
把错误看作由于程序员的弱点所造成,而应该
把它看成由于程序开发的困难而固有的。对错
误要追根到底
5.2.3 静态检验
? 静态检查可以看作一个人参加的程序审查会,
或一个人参加的人工运行。让一个人读程序,
依照查错表来检查程序或用测试数据把程序
,走, 一遍。
5.3 测试数据的设计
? 5.3.1 逻辑覆盖测试(白盒测试方法)
例:
两个判定(菱形部分)和四个条件( A>1,B=0,A=2,X>1)
P R O C E D U R E p r o 1
p a r a m e t e r A,B,X
i f ( A > 1 ), A N D, ( B = 0 )
X = X / A
e n d i f
i f ( A = 2 ), O R, ( X > 1 )
X = X + 1
e n d i f
A > 1
A N D
B = 0
X = X /A
A = 2
OR
X > 1
X = X + 1
Y
Y
N
N
a
c
b
e
d
? 1、语句覆盖:
– 编写足够的测试数据,使得每条语句至少执
行一次
– 路径 ace 满足覆盖要求
– 设计的测试数据,A= 2; B= 0; X= 3
– 问题,如果第一个判定被错误地写成, OR”,
这个错误就检查不出来。同样如果将第二个
判定中, X> 1”写成, X> 0”,也将检查不
出错误。
? 2, 判定覆盖
– 编写足够的测试数据,使得每个判定至少有
一次, 真, 和一次, 假, 的结果。或者说,
每个分支方向都必须至少经过一次。
– 路径 ace,bad或路径 acd,abe都可以满足覆
盖要求
– 设计的测试数据:
?A= 3,B= 0,X= 3
?A= 2,B= 1,X= 1
– 问题,若第二个判定有错( X> 1被错误地写
成 X< 1),用路径 acd及 abe就检测不出这个
错误
? 3, 条件覆盖
– 编写足够的测试数据,以使判定中每个条件的所有
可能结果至少出现一次 。
– 四个条件,A> 1,B= 0,A= 2和 X> 1,因此需要
有足够的测试数据以形成:在 a点出现 A> 1,A≤ 1,
B= 0,B≠ 0。 在 b点出现 A= 2,A≠ 2,X> 1,
X≤ 1
– 设计的测试数据:
? A= 2,B= 0,X= 4,执行路径 ace
? A= 1,B= 1,X= 1,执行路径 abd
– 问题,当测试判定条件 IF( A,AND,B) 或 IF
( A,OR,B) 一个条件的, 真, 或, 假, 会掩盖另
一个条件的错误。
? 4,判定 /条件覆盖
– 编写足够的测试数据,使得判定中每个条件
的所有可能结果至少出现一次,每个判定本
身所有可能结果也至少出现一次 。
? 5,多重条件覆盖
– 编写足够的测试数据使得每个判定中条件结果的所
有可能组合至少出现一次
? ① A> 1,B= 0
? ② A> 1,B≠0
? ③ A≤1,B= 0
? ④ A≤1,B≠0
? ⑤ A= 2,X> 1
? ⑥ A= 2,X≤1
? ⑦ A≠2,X> 1
? ⑧ A≠ 2,X≤ 1
– A= 2,B= 0,X= 4 覆盖 ①, ⑤
– A= 2,B= 1,X= 1 覆盖 ②, ⑥
– A= 1,B= 0,X= 2 覆盖 ③, ⑦
– A= 1,B= 1,X= 1 覆盖 ④, ⑧
5.3.2 等价类划分 (黑盒测试方法)
? 测试数据设计步骤:
– ( 1)划分等价类
– ( 2)找出测试数据
? 确定等价类的几条原则
– 1、如果某个输入条件规定了值的范围,可以确定一个有效等
价类和两个无效等价类 。
– 2、如果一个输入条件规定了值的个数,就可以确定一个有效
等价类和两个无效等价类。
– 3、如果一个输入条件规定了一个输入值的集合,则对集合中
每个元素可以确定一个等价类(在集合中的元素),同时可
以对集合确定一个无效等价类(不在集合中的元素)。
– 4,如果一个输入条件规定了, 必须如何, 的条件则可以确定
一个有效等价类和一个无效等价类 。
– 5、如果有理由确信某一个等价类中的各元素在程序中的处理
方式是有区别的,那就应把这个等价类分成更小的等价类。
确定测试数据( Identifying the Testing Cases)
? 1,给每个等价类规定一个唯一的编号 。
? 2,设计一个新的测试数据, 使其尽可能多地
覆盖未被覆盖的有效等价类, 直到所有有效等
价类都被覆盖为止 ( 即每个有效等价类都包含
于某个或某些测试数据中 ) 。
? 3,设计出一个测试数据, 使其仅仅覆盖一个
未被覆盖的无效等价类, 直到覆盖了全部无效
等价类 。
举例,
? 假设 DIMENSION 语句用来规定数组维数 。
DIMENSION语句的形式是:
? DIMENSION AD[,AD]……
? 其中 AD是数组描述符, 其形式是,NN( d[,d]) 。
NN是数组名, d是维数说明符 。 数组名可以是 1至 6个
字母或数字, 但其第一个字符必须是字母 。 数组可以
定义的维数是 1或 2,维数说明符的形式是
? [lb,]ub
? lb和 ub分别表示维数的上, 下界 。 上下界可以是 -
65534至 65535的常数, 也可以是整型变量名 ( 但不能
是数组元素名 ) 。 如果没有规定 lb,则假设其值为 1,
ub的值一定要大于或等于 lb。 若规定了 lb,它的值可
以是负数, 零或正数 。 DIMENSION语句可以连续写
多行 。
确定等价类:
输入条件 有效等价类 无效等价类
数组描述符个数 1(1),> 1(2) 无 (3)
数组名长度 1-6(4) 0(5),> 6(6)
数组名 有字母 (7),有数字 (8) 其它 (9)
数组名以字母开头 是 (10) 不是 (11)
数组维数 1-2(12) 0(13),> 2(14)
上界是 常数 (15),整型变量名 (16) 数组元素名 (17),其它 (18)
整型变量名 有字母 (19),有数字 (20) 其它 (21)
整型变量以字母开始 是 (22) 不是 (23)
常数 -65534~ 65535(24) < -65534(25),> 65535(26)
定义下界否 是 (27),没有 (28)
上界对下界关系 大于 (29),等于 (30) 小于 (31)
下界定义为 负数 (32),0(33),> 0(34)
下界是 常数 (35),整型变量 (36) 数组元素名 (37),其它 (38)
多于一行否 是 (39),不是 (40)
设计测试数据:
? 写出测试数据, 使其覆盖一个或多个有效等价类 。
? DIMENSION AEE( 2),
– 覆盖 1,4,7,10,12,15,24,28,29和 40这几个等价
类 。
? DIMENSION A12345( 1,KLM), BBB( -65534,100,
0,100), FFF( 10,10,1,65535)
– 覆盖了其余的等价类 。
为每一个无效等价类设计一个测试数据
? (3),DIMENSION
? (5),DIMENSION (10)
? (6),DIMENSION A234567(2)
? (9),DIMENSION A.1(2)
? (11),DIMENSION 1 A(10)
? (13),DIMENSION B
? (14),DIMENSION B(4,4,4)
? (17),DIMENSION B(4,A(2))
? (18),DIMENSION B(4,,7)
? (21),DIMENSION C(1.,10)
? (23),DIMENSION C(10,1J)
? (25),DIMENSION D(-65535,1)
? (26),DIMENSION D(65536)
? (31),DIMENSION D(4,3)
? (37),DIMENSION D(A(2),4)
? (38),DIMENSION D(.,4)
5.3.3 边值分析
– 边值条件是指在输入与输出等价类直接边缘上,稍高于
其边界和低于其边界的这些状态条件
? 原则:
– 1、如果输入条件规定了值的范围,写出这个范围的边
界测试数据以及刚刚超出范围的无效测试数据
– 2、如果输入条件规定了值的个数,分别对值的最大个
数、最小个数、稍小于最小个数和稍大于最大个数的状
态写出测试数据
– 3、对每个输出条件使用第 1条
– 4、对每个输出条件使用第 2条
– 5、如果程序的输入或输出是个有序集,则应把注意力
集中在集合的第一个和最后一个元素上。
– 6、另外可以找出其它的边界条件
5.3.4 因果图 ( 黑盒测试方法)
? 例:
– 第一列字符必须是 A或 B,第二列字符必须是一个数
字。在这种情况下,修改文件。如果第一个字符不
正确,则发出信息 X12。 如果第二个字符不是数字,
则发出信息 X13。
– 表示为:
– 1——第 1列字符是 A
– 2——第 1列字符是 B
– 3——第 2列字符是一个数字
– 结果是:
– 70——修改文件
– 71——发出信息 X12
– 72——发出信息 X13
基本符号:
a b a b b d
c
a
c
b
a
v
^
恒等 非 或 与
b
a
E b
c
a
I
b
a
O
唯一
b
a
R
要求
b
a
M 约束
约束符号:
因果图实例:
71
v
^ 70
72
11
1
2
3
71
v
^ 70
72
11
1
2
3
E
( A ) ( B )
测试数据的设计步骤如下,
? 1、将模块说明书中的规范说明分成若干个可工
作的部分
? 2、标识出规范中的原因和结果
? 3、分析规范中的语义内容,并将其转换成连接
原因与结果的因果图
? 4、由于语法或环境的限制,存在有不可能的原
因与(或)结果的组合情况,对此用约束条件在
因果图上加以注释
? 5、通过有条理地跟踪图中的状态条件,将因果
图转换成有限项的判定表
? 6、将判定表中的每一列都转换成一个测试数据
按因果图绘制判定表:
1 1 0 1 0 0 0
2 0 1 0 1 0 0
3 1 1 0 0 0 0 1
70 1 1 0 0 0
71 0 0 0 0 1 1
72 0 0 1 1 0 1 0
? 根据判断表的取值可以写出测试数据如下:
? 1,A2 ( 70)
? 2,B3 ( 70)
? 3,AE ( 72)
? 4,BS ( 72)
? 5,XX ( 71,72)
? 6,S4 ( 71)
? 7,S ( 71)
5.3.5 猜错
? 猜错技巧大抵可以说是一种凭直觉的特定过程,
所以很难定出机械的执行步骤。基本思想就是
列出可能有的错误和易错情况表,在这个表的
基础上写出测试数据。
5.4 模块测试
? 模块测试(或称程序单元测试):是指测试程
序中的单个子程序,进而延伸至整个模块
? 模块测试的目的:是要对模块的功能与定义模
块的性能规范或接口规范进行比较
? 测试过程是:用什么方法来设计测试数据;应
该按什么次序测试及组合模块;提出一些有关
进行测试的切实建议
5.3.6 策略( The Strategy)
? 1,如果设计规范含有输入条件的组合, 便从因果图开
始 。
? 2,不管情况怎样, 都使用边值分析方法, 记住要分析
输入和输出的边界 。 边值分析方法能给我们补充一批
测试条件 。
? 3,对输入和输出划分有效和无效的两个等价类, 如果
必要补充前面已经确定的测试数据 。
? 4,用猜错技巧再增加一些测试数据 。
? 5,按照得到测试数据集审查程序的逻辑 。 审查的方法
是使用判定覆盖, 条件覆盖, 判定条件覆盖或多重条
件覆盖准则 。 如果前四步产生的测试数据没有满足覆
盖准则, 适当增加足够的测试数据以满足准则 。
模块测试测试方式
? 两个概念:
– 驱动模块:是另外编写的小模块,用来驱动
或传送测试数据给被测模块
– 桩模块:是另外编写的小模块,用来模拟被
调用模块的功能
? 测试方式
– 非增式测试
– 增式测试
示例:
A
B C D
E F
非增式测试:
? 非增式测试方式是:先对示例的六个模块中的
每一个进行测试,也就是把每个模块当做独立
的整体来测试。根据测试环境和参加测试的人
数等情况来决定是同时进行测试还是逐个地测
试各个模块,测试完毕后再把这些模块组合
(联接)起来形成程序。
? 条件:需要 5个驱动模块和 5个桩模块
增式测试:
? 增式测试:它不孤立地测试每一个模块,而是一开始
就把待测模块与已测过的模块集合联接起来
? 种类:
– 自顶向下测试:
?测试顺序,A——A,B,C,D——A,B,C,D,E,F
?条件,5个桩模块
– 自底向上测试:
?测试顺序,E,C,F——B,E,C,D,F——A,B,C,D,E,F
?条件,5个驱动模块
需要的说明:
? 1、非增式测试方式需要更多的工作量
? 2、增式测试使模块之间接口的错误能够被较早地检查
出来,改错也比较容易;若用非增式测试,当子模块
最后被合成时,错误可能在程序的任何地方,很难确
定出错位置,因而也不利于修改。
? 3、增式测试对程序地检查可能会更加彻底
? 4、非增式测试方法只需要用较少的机器时间
? 5、用非增式测试方式在模块测试阶段的开始就有可能
进行并行的工作
5.4.2 自顶向下测试
? 自顶向下测试( Top_Down Testing) 是从顶端模块
(即程序开头的模块)开始的测试 。
? 制定测试顺序的原则:
– 下一次测试的模块至少有一个调用它的模块已经测
试过
– 如果程序中有关键性的部分,设计次序应尽早地把
这些模块加入程序。所谓, 关键部分, 可能是一个
复杂的模块,一个具有新算法的模块,或怀疑容易
出错的模块
– 设计次序时,要让含有输入 /输出的模块尽早地加入
到测试中。
? 参考顺序:
? A,B,C,D,E,F
? A,B,E,C,D,F
? A,C,B,E,D,F
? A,D,F,C,B,E
A
B C D
E F
5.4.3 自底向上测试
? 自底向上测试( Bottom_Up Testing) 的方法
是从程序的末端模块(即不调用别的模块的
,叶子, 模块)开始测试。
? 制定测试顺序的原则是:所有下层模块(即它
能调用的所有模块)必须事先都被测试过。
? (请自行给出测试顺序)
? 自顶向下测试的优点是:
– 1,如果主要的错误趋向于发生在程序的顶端时, 有利于
查出错误 。
– 2,一旦加入了 I/O功能, 测试数据很容易描述 。
– 3,初期的程序设计轮廓可以让人们看到程序的功能, 并
使人们增强工作信心 。
? 自顶向下测试的缺点是:
– 1,需要考虑桩模块 。
– 2,桩模块比想象的更复杂 。
– 3,在 I/O功能加入之前, 桩中很难描述测试数据 。
– 4,不可能或很难产生测试条件 。
– 5,很难观察测试输出 。
– 6,使人想到设计和测试同时进行 。
– 7,会使人想推迟完成某些模块的测试 。
? 自底向上测试的优点是:
– 1,如果主要错误发生在程序底端则是很有用的 。
– 2,容易产生测试条件 。
– 3,很容易观察测试结果 。
? 自底向上测试的缺点是:
– 1,必须给出驱动模块 。
– 2,在加入最后一个模块之前, 程序不能作为一个
整体存在 。
5.4.4 测试的执行
? 建议和原则:
? 当模块的实际结果与期望结果不吻合,则可能有两种
解释:一是模块可能有错误,二是期望的结果是错的
(即测试数据不正确)。为了尽量减少这种混乱,应
该首先复查测试数据集再去进行测试。
? 利用自动测试工具能尽量减少测试过程的单调工作
? 在准备测试模块时,要注意测试中的心理和经济上的
原则;记住确定期望结果是测试数据的一个必要部分;
当执行测试时,要注意寻找副作用,即模块做了并没
要求做的事情。
? 当采用模块测试时,程序员可以相互交换模块,而不
是去测试自己的模块。要避免丢掉测试数据,应该用
一种将来能重新使用的形式来描述测试数据。
? 模块测试的目的 不是证明模块功能的正确性,而是证
明模块中存在的错误。
5.5 高级测试
? 5.5.1 功能测试
– 功能测试的目的 是要找出系统功能与外部规
范(系统功能设计)之间的不一致
– 功能测试时要注意的问题是:
– 1,要考虑到那些不合理的和意想不到的输
入条件 。
– 2,要将预期结果的定义做为测试数据的重
要部分
– 3,功能测试的目的是暴露错误, 而不是证
明程序符合外部规范 。
5.5.2 系统测试
? 1、业务流程测试( Procedure Testing)
? 2、机能测试( Facility Testing)
? 3、批量测试( Volume Testing)
? 4、强度测试( Stress Testing)
? 5、便利性测试( Usability Testing)
? 6、安全性测试( Security Testing)
? 7、性能测试( Performance Testing)
? 8、存储量测试( Storage Testing)
? 9、配置测试( Configuration Testing)
? 10、兼容 /变换测试( Compatibility/Conversion Testing)
? 11、可靠性测试( Reliablity Testing)
? 12、恢复测试( Recovery Testing)
? 13、可安装性测试( Installability Testing)
? 14、可用性测试( Serviceability Testing)
? 15、文件资料测试( Documentation Testing)
5.5.3 验收测试及安装测试
? 验收测试往往由程序的用户自己做。如果是按合
同来进行的开发,则合同的签署机构(用户)把
程序操作与合同相比较,从而进行验收测试。
? 安装测试的目的不是找出软件错误,而是找出安
装错误。
5.6 测试计划和控制
? 5.6.1 测试计划
– 1、目的
– 2、完成的标准
– 3、时间安排
– 4、明确责任
– 5、测试数据库及其标准化
– 6、工具
– 7、机器时间
– 8、硬件配置
– 9、组装方式
– 10、记录手段
– 11、纠错手段
– 12、回归测试
5.6.2 测试完成的标准
? 常用的完成标准:
– 1、测试超过了预定的时间表则停止测试
– 2、执行了所有测试数据但没有发现错误,则停止
测试。
? 比较有效的完成标准:
– 第一类(不是最好的):把使用了特定测试数据设
计方法作为判断完成测试的基础
– 第二类:正面指出完成测试的要求,譬如可以认为
某一模块的模块测试只有找出 3个错误才算完成等

– 第三类:用图标出某个测试阶段中单位时间查出错
误的数量,通过分析这一曲线,可以确定应继续测
试还是结束这一测试阶段而开始下一测试阶段。