文章目录
- 1 软件测试
- 1.1 软件测试的目的和原则
- 1.2 软件测试的对象
- 1.3 软件测试的步骤
- 1.4 软件测试技术
- 1.4.1 白盒测试技术
- 1.4.2 黑盒测试技术
- 1.4.2.1 等价类划分法
- 1.4.2.2 边界值分析法
- 1.4.2.3 错误推断法
- 1.5 调试
- 2 面向对象测试
- 2.1 测试策略
- 2.2 设计测试用例
- 2.2.1 测试类的方法
- 2.2.1.1 随机测试
- 2.2.1.2 划分测试
- 2.2.1.3 基于故障的测试
- 2.2.2 集成测试方法
- 2.2.2.1 多类测试
- 2.2.2.2 从动态模型导出测试用例
1 软件测试
1.1 软件测试的目的和原则
在软件开发的前期不可避免地会引入错误,进行软件测试是为了发现和改正错误。软件测试的特点如下:
1、开销大。据统计,软件测试的开销大约占总成本的30%-50%。
2、不能进行“穷举”测试。只有将所有可能的情况都测试到,才有可能检查出所有的错误,但显然这是不可能的。
3、要查出尽可能多的错误,这导致软件测试的难度很大。
因此,软件测试需要选择高效的测试用例。软件测试的目的如下:
1、测试是为了发现程序中的错误而执行程序的过程;
2、一个好的测试用例是发现了迄今为止尚未发现的错误的测试用例;
3、一次成功的测试是发现了至今为止尚未发现的错误的测试。
软件测试的原则如下:
1、尽早并且不断地测试。
2、程序员检查自己的程序非常正常,但是正式的测试工作应该由独立且专业的软件测试机构来完成。
3、设计测试用例时:
- 测试用例由输入数据和预期输出结果构成;
- 既要有合理的输入数据,也要有不合理的输入数据,并考虑各种边界条件;
- 注意要长期地保存测试用例。
4、尽量避免测试中的错误群集现象发生,这与程序员的编程水平和习惯有很大的关系。
5、对测试错误的结果一定要有一个确认的过程:由人员A测试出来的错误,一定要有另一个人员B来确认,严重的错误可以召开评审会进行讨论和分析。
6、制定严格的测试计划,并把测试时间安排得尽量宽松,不要希望在极短的时间内完成一个高水平的测试。
7、回归测试(指修改了旧代码后,重新测试以确认修改没有引入新错误的过程)的关联性一定要引起充分的注意,修改一个错误而引起更多新的错误出现的现象并不少见。
8、妥善保存一切在测试过程中生成的文档,因为重现测试往往要靠之前的测试文档。
1.2 软件测试的对象
软件测试并不等于程序测试,软件测试应贯穿在软件定义与开发的整个期间。
需求分析、概要设计、详细设计及程序编码等阶段所得到的文档,包括需求规格说明书、概要设计说明书、详细设计规格说明书以及源程序,都可成为测试的对象。
1.3 软件测试的步骤
传统软件测试的最小单元是模块。步骤如下:
1、单元测试:又称为模块测试,可在编码阶段进行。主要检查模块是否实现了详细设计说明书中规定的模块功能和算法,并且发现编码和详细设计中产生的错误。单元测试通常采用白盒测试技术。
2、集成测试:又称为组装测试。对由各模块组装而成的新模块进行测试,主要检查模块之间的接口和通信,并且发现设计阶段产生的错误。集成测试通常采用黑盒测试技术。
3、确认测试:通过所提供的客观证据去检测与证实软件是否满足软件需求说明书中规定的需求。
4、验收测试:按照项目任务书或合同、供需双方约定的验收依据文档进行的对整个系统的测试与详审,决定最终是否接收系统。
1.4 软件测试技术
1.4.1 白盒测试技术
白盒法又称为逻辑覆盖法,该方法把程序看成装在一只透明的白盒子里,测试者完全了解程序的结构和处理过程,主要根据程序的内部逻辑来设计测试用例,检查程序中的逻辑通路是否按预定的要求正确地运行。逻辑覆盖利用测试数据,对运行着的被测程序进行程序逻辑覆盖程度的判断,测试用例的选择是按照不同覆盖标准确定的,主要的覆盖标准有以下5种:
1、语句覆盖:执行足够的测试用例,使得程序中每个语句至少都能被执行一次。
2、判定覆盖:执行足够的测试用例,使得程序中每个判定至少都获得一次“真”值和“假”值。
3、条件覆盖:执行足够的测试用例,使得判定中的每个条件获得各种可能的结果。
4、判定/条件覆盖:执行足够的测试用例,使得判定中每个条件取到各种可能的值,并使每个判定取到各种可能的结果。
5、条件组合覆盖:执行足够的测试用例,使得每个判定中条件的各种可能组合都至少出现一次。
下面是一段代码:
fun(A,B,X) //X是实数
if A>1&&B=0
X=X/A
if A=2||X>1
X=X+1
其流程图如下:
将上图的某些流程顺序标上字母为:
下面用白盒技术测试中的5种覆盖标准对上述程序段进行测试用例的选择,测试用例的格式为:[(A,B,X),(A,B,X)],分别对应输入与预期输出。如下:
1、语句覆盖:使得程序中每个语句至少都能被执行一次。满足条件的执行路径:a-c-b-e-d。选择用例:[(2,0,4),(2,0,3)]。
2、判定覆盖:使得程序中每个判定至少为TRUE或FALSE各一次。满足条件的执行路径:a-c-b-e-d∩a-b-d或者a-b-e-d∩a-c-b-d。选择用例:
(1)a-c-b-e-d∩a-b-d:[(2,0,4),(2,0,3)],[(1,1,1),(1,1,1)]。
(2)a-b-e-d∩a-c-b-d:[(2,1,1),(2,1,2)],[(3,0,3),(3,0,1)]。
3、条件覆盖:使得判定中的每个条件获得各种可能的结果。应满足以下覆盖情况:
(1)判定一:A>1,A≤1,B=0,B≠0;
(2)判定二:A=2,A≠2,X>1,X≤1。
选择用例:
(1)[(2,0,4),(2,0,3)];
(2)[(1,1,1),(1,1,1)]。
4、判定/条件覆盖:同时满足判断覆盖和条件覆盖。应满足以下覆盖情况:
(1)A>1,A≤1,B=0,B≠0;
(2)A=2,A≠2,X>1,X≤1。
应执行路径a-c-b-e-d∩a-b-d或者a-c-b-d∩a-b-e-d。选择用例:
(1)a-c-b-e-d:[(2,0,4),(2,0,3)];
(2)a-b-d:[(1,1,1),(1,1,1)]。
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。
选择用例:
(1)①⑤:[(2,0,4),(2,0,3)];
(2)②⑥:[(2,1,1),(2,1,2)];
(3)③⑦:[(1,0,3),(1,0,4)];
(4)④⑧:[(1,1,1),(1,1,1)]。
除了上述5条覆盖,还可以考虑基本路径测试:设计足够的测试用例,使被测程序中每条可能执行的路径都至少经过一次(如果有环路,则要求每条环路至少经过一次)。对本例,所有可能的路径有四条:a-c-b-e-d、a-b-d、a-c-b-d、a-b-e-d。可用4个测试用例:
(1)a-c-b-e-d:[(2,0,4),(2,0,3)];
(2)a-c-b-d:[(3,0,3),(3,0,1)];
(3)a-b-e-d:[(1,0,2),(1,0,3)];
(4)a-b-d:[(1,1,1),(1,1,1)]。
1.4.2 黑盒测试技术
把程序看成装在一只黑盒子里,测试者完全不了解(或不考虑)程序结构和处理过程。它根据说明书规定的功能来设计测试用例,检查程序的功能是否符合规格说明书的要求。
黑盒测试技术有:等价类划分法、边界值分析法、错误推断法等。
1.4.2.1 等价类划分法
将输入数据分为有效数据和无效数据两类:
1、有效数据:符合规格说明的合理的输入数据;
2、无效数据:不符合规格说明的合理的输入数据。
将这些输入数据划分成相应的若干个等价类:有效的等价类和无效的等价类,那么可以假定:
1、如果等价类中的一个输入数据能检测出一个错误,那么等价类中的其它输入也能检测出同一个错误。
2、如果等价类中的一个输入数据未检测出错误,那么等价类中的其它输入也不应检测出错误。
下面是3条有助于等价类划分的启发式规则:
1、如果规定了输入值的范围,则可划分一个有效的等价类(输入值在此范围),两个无效的等价类(输入值小于最小值或大于最大值)。
2、如果规定了输入数据的个数,则可划分一个有效的等价类(输入值个数等于规定个数)、两个无效的等价类(输入值个数大于或小于规定个数)。
3、如果规定了输入数据的一组值,且程序对不同输入值做不同处理,则每个允许的输入值是一个有效等价类,而且还包括一个无效的等价类(任一个不允许的输入值)。
下面是一个示例。
某程序要求输入某城市的电话号码,电话号码由三个部分组成,其名称与内容分别是:
- 地区码:空白或三位数字;
- 前缀:非“0”或非“1”开头的三位数字;
- 后缀:四位数字。
假定被测试的程序接收符合上述规则的所有号码,拒绝不符合规则的号码,现在使用等价类划分法来对其进行测试。
1、第一步:划分等价类:
输入条件 | 有效等价类 | 无效等价类 |
地区码 | 空白(1),3位数字(2) | 有非数字字符(5);少于三位数字(6);多于三位数字(7); |
前缀 | 从200-999之间的数字(3) | 有非数字字符(8);起始位为0(9);起始位为1(10);少于三位数字(11);多于三位数字(12); |
后缀 | 4位数字(4) | 有非数字字符(13);少于四位数字(14);多于四位数字(15) |
2、第二步:确定测试用例。上表中有四个有效等价类,可使用下面两个测试用例:
测试数据 | 测试范围 | 预期结果 |
()276-2345 | (1)(3)(4) | 有效 |
(635)805-9321 | (2)(3)(4) | 有效 |
对于11个无效等价类,应选取11个测试用例:
测试数据 | 测试范围 | 预期结果 |
(a)276-234 | (5) | 无效 |
… | … | … |
… | … | … |
… | … | … |
… | … | … |
(偷懒不写啦)
1.4.2.2 边界值分析法
经验表明,处理边界情况时最易发生错误,如数组的下标、循环等。示例如下:
在使用边界值分析法进行测试程序时,在测试用例的选取上遵循的规则如下:
1、如果输入条件规定了取值范围,则应对该范围的边界内附近、恰好在边界上和边界外附近设计测试用例。例:输入值的有效范围为[1.0,10.0],则应对0.9,1.0,1.1,9.9,10.0,10.1等数据设计测试用例。
2、如果输入条件规定了数据的个数,则应对最小个数、最大个数、比最小个数少1、比最大个数多1等情况进行设计测试用例。
1.4.2.3 错误推断法
错误推断法是一种凭直觉和经验推测某些可能存在的错误,从而针对这些可能存在的错误设计测试用例的方法,适用于对各种输入数据的组合测试情况。等价类划分和边界值分析法都只孤立地考虑了各个输入数据的测试功效,而没有考虑多个数据组合时的功效。在黑盒测试中,着重检查输入条件的组合错误推断法。
1.5 调试
调试是在测试发现错误之后排除错误的过程,大多数的IDE(Integrated Development Environment,集成开发环境)中都提供了调试工具。软件调试的目的是改正错误。
调试过程如下:
调试的途径有:
1、蛮干法;
2、回溯法:适应于小的程序;
3、原因排除法:包括对分查找法、归纳法、演绎法等。
2 面向对象测试
2.1 测试策略
OOT,Object-Oriented Test,即面向对象测试。
OOT是在传统测试方法的基础上添加了适应于OO特点的技术和方法,包括:单元测试、集成测试和确认测试。其中:
1、面向对象单元测试中单元的概念发生了变化,最小的可测试单元是封装起来的类和对象。在测试OO时,不能再孤立地测试单个操作,而应该把操作作为类的一部分来测试。
2、面向对象集成测试的测试策略有两种:
- 基于线程的测试:把响应系统的一个输入或一个事件所需要的那些类集成起来,分别集成并测试每个线程,同时应用回归测试(指修改了旧代码后,重新测试以确认修改没有引入新错误的过程),以保证没有产生副作用。
- 基于使用的测试:首先测试独立类,把独立类都测试完之后,再测试使用独立类的下一个层次的类——依赖类,再测试依赖类的依赖类,直到把软件系统测试完为止。集成测试应注意发现那些不同类之间的协作错误。
3、面向对象确认测试集中检查用户可见的动作和用户可识别的输出,可用传统的黑盒测试技术去设计测试用例,但主要还是根据动态模型和描述系统行为的脚本来设计确认测试用例。
2.2 设计测试用例
与传统软件测试用例的设计有所不同,OOT关注于设计适当的操作序列以检查类的状态。
2.2.1 测试类的方法
测试类的方法着重测试单个类和类中封装的方法。测试方法主要有:随机测试、划分测试、基于故障的测试。
2.2.1.1 随机测试
随机测试的思想如下:
1、找出最小测试序列;
2、定义最大测试序列;
3、从最大测试序列中随机产生一组操作序列,就可得到一个测试用例。
下面是随机测试的一个示例。
在银行应用中的Account类有以下操作:open、setup、deposit、withdraw、balance、summarize、creditLimit、close。
则:
1、最小序列:open、setup、deposit、withdraw、close;
2、最大序列:open、setup、deposit、[deposit|withdraw|balance|summarize|creditLimit]n、withdraw、close;
3、随机测试用例:open、setup、deposit、deposit、balance、summarize、withdraw、close。
2.2.1.2 划分测试
划分测试与等价类划分方法类似——也是对输入和输出进行分类,然后针对每个类设计相应的测试用例。主要方法如下:
1、基于状态的划分。根据类操作是否改变类状态来划分操作。例如在上述的Account类中,状态操作包括deposit、withdraw;非状态操作包括balance、summarize。
2、基于属性的划分。根据类操作使用的属性来划分类操作,然后为每个类别设计测试序列。例如在Account类中,用balance来划分,从而把操作划分为3个类别:
- 使用balance的操作;
- 修改balance的操作;
- 不使用也不修改balance的操作。
3、基于功能的划分。根据类操作所完成的功能来划分操作。例如可把Account类中的操作分类为初始化操作(open,setup)、计算操作(deposit,withdraw)、查询操作(balance,summarize,creditLimit)和终止操作(close)。
2.2.1.3 基于故障的测试
基于故障的测试与传统的错误推断法类似:先推测软件中可能有的错误,然后设计出最可能发现这些错误的测试用例。
2.2.2 集成测试方法
集成测试方法对类间协作进行测试。方法有:多类测试,从动态模型导出测试用例等。
2.2.2.1 多类测试
以银行系统的类-协作图为例说明这一测试方法的应用:
现在考虑Bank类相对于ATM类的操作序列:verifyAcct、verifyPIN、[(verifyPolicy、withdrawReq)|depositReq|acctInfoReq]n。针对如下操作序列:verifyAcct、verifyPIN、depositReq,添加类之间的协作信息,则可得如下操作序列:verifyAcctBank、[validAcctvalidationlnfo]、verifyPINBank、[validPINvalidationlnfo]、depositReqBank、[depositAccount]。
2.2.2.2 从动态模型导出测试用例
Acount类的状态转换图如下:
设计的测试用例应覆盖所有状态,即操作序列应使Account类的实例遍历所有允许的状态转换。如下:
1、操作序列1(是最小序列):open、setupAccnt、deposit(initial)、withdraw(final)、close;
2、操作序列2:open、setupAccnt、deposit(initial)、deposit、balance、credit、withdraw(final)、close。
END