(1) 通常应该避免依赖先前测试用例的输出,测试用例的执行序列早期发现的错误可能导致其他的错误而减少测试执行时实际测试的代码量;
(2) 测试用例设计过程中,包括作为试验执行这些测试用例时,常常可以在软件构建前就发现BUG。还有可能在测试设计阶段比测试执行阶段发现更多的BUG。
(3) 在整个单元测试设计中,主要的输入应该是被测单元的设计文档。在某些情况下,需要将试验实际代码作为测试设计过程的输入,测试设计者必须意识到不是在测试代码本身。从代码构建出来的测试说明只能证明代码执行了代码完成的工作,而不是代码应该完成的工作。
步骤1:首先使被测单元运行
任何单元测试说明的第一个测试用例应该是以一种可能的简单方法执行被测单元。看到被测单元第一个测试用例的运行成功可用增强人的自信心。如果不能正确执行,最好选择一个尽可能简单的输入对被测单元进行测试/调试。
这个阶段适合的技术有:
A.模块设计导出的测试
B.对等区间划分
步骤2:正面测试(Positive Testing)
正面测试的测试用例用于验证被测单元能够执行应该完成的工作。测试设计者应该查阅相关的设计说明;每个测试用例应该测试模块设计说明中一项或多项陈述。如果涉及多个设计说明,最好使测试用例的序列对应一个模块单元的主设计说明。
适合的技术:
A.设计说明导出的测试
B.对等区间划分
C.状态转换测试
步骤3:负面测试(Negative Testing)
负面测试用于验证软件不执行其不应该完成的工作。这一步骤主要依赖于错误猜测,需要依靠测试设计者的经验判断可能出现问题的位置。
适合的技术有:
A.错误猜测
B.边界值分析
C.内部边界值测试
D.状态转换测试
步骤4:设计需求中其它测试特性用例设计
如果需要,应该针对性能、余量、安全需要、保密需求等设计测试用例。在有安全保密需求的情况下,重视安全保密分析和验证是方便的。针对安全保密问题的测试用例应该在测试说明中进行标注。同时应该加入更多的测试用例测试所有的保密和安全冒险问题。
适合的技术:
设计说明导出的测试
步骤5:覆盖率测试用例设计
应该或已有测试用例所达到的代码覆盖率。应该增加更多的测试用例到单元测试说明中以达到特定测试的覆盖率目标。一旦覆盖测试设计好,就可以构造测试过程和执行测试。覆盖率测试一般要求语句覆盖率(100%)、分支覆盖率(100%)等。
适合的技术:
A.分支测试
B.条件测试
C.数据定义-使用测试
D.状态转换测试
步骤6:测试执行
使用上述5个步骤设计的测试说明在大多数情况下可以实现一个比较完整的单元测试。到这一步,就可以使用测试说明构造实际的测试过程和用于执行测试的测试过程。该测试过程可能是特定测试工具的一个测试脚本。
测试过程的执行可以查出模块单元的错误,然后进行修复和重新测试。在测试过程中的动态分析可以产生代码覆盖率测量值,以指示覆盖目标已经达到。因此需要在测试设计说明中需要增加一个完善代码覆盖率的步骤。
步骤7:完善代码覆盖
由于模块单元的设计文档规范不一,测试设计中可能引入人为的错误,测试执行后,复杂的决策条件、循环和分支的覆盖率目标可能并没有达到,这时需要进行分析找出原因,导致一些重要执行路径没有被覆盖的可能原因有:
A.不可行路径或条件―― 应该标注测试说明证明该路径或条件没有测试的原因。
B.不可到达或冗余代码―― 正确处理方法是删除这种代码。这种分析容易出错,特别是使用防卫式程序设计技术(Defensive Programming Techniques)时,如有疑义,这些防卫性程序代码就不要删除。
C.测试用例不足―― 应该重新提炼测试用例,设计更多的测试用例添加到测试说明中以覆盖没有执行过的路径。
理想情况下,覆盖完善阶段应该在不阅读实际代码的情况下进行。然而,实际上,为达到覆盖率目标,看一下实际代码也是需要的。覆盖完善步骤的重要程度相对小一些。最有效的测试来自于分析和说明,而不是来自于试验,依赖覆盖完善步骤补充一份不好的测试设计。
适合的技术:
A.分支测试
B.条件测试
C.设计定义――试验测试
D.状态转换测试
黑盒测试:使用单元接口和功能描述,不需了解被测单元的内部结构
白盒测试:使用被测单元内部如何工作的信息
其他技术:不属于以上2类
白盒测试用例设计:使用程序设计的控制结构导出测试用例。
采用白盒测试的目的主要是:
A.保证一个模块中的所有独立路径至少被执行一次;
B.对所有的逻辑值均需要测试真、假两个分支;
C.在上下边界及可操作范围内运行所有循环;
D.检查内部数据结构以确保其有效性。
黑盒测试用例设计:使用详细设计导出测试用例。
采用黑盒测试的目的主要是:
A.检查功能是否实现或遗漏;
B.检查人机界户是否错误;
C.数据结构或外部数据库访问错误;
D.性能等其它特性要求是否满足;
E.初始化和终止错误。
测试用例通过根据相关的软件设计说明文档进行设计。每个测试用例测试设计说明中一项或多项陈述。通常为被测单元设计说明的一系列陈述建立一系列对应的设计用例。
例1:考虑下面计算实数平方根的函数的设计说明:
输入:实数
输出:实数
处理:当输入0或大于0时,返回输入数的平方根;当输入小于0时,显示:“Square root error - illegal negative input",并返回0;库函数Print用于显示出错信息。
设计说明有3个陈述,可以2个测试用例来对应。
Test Case 1:输入4,返回2。//执行第一个陈述
Test Case 2:输入-10,返回0,显示“Square root error - illegal negative input”//对应第二个和第三个陈述
设计说明导出的测试用例提供了与被测单元设计说明陈述序列很好的对应关系,增强了测试说明的可读性和可维护性。但有软件设计说明导出测试是正面的测试用例设计技术。软件设计说明导出的测试应该用负面测试用例进行补充,以提供一个完整的单元测试说明。设计说明导出的测试设计技术还可用于安全分析、保密分析、软件冒险分析和其他给单元设计的其他补充文档。
基本路径测试是一种白盒测试技术。测试用例设计者导出一个过程设计的逻辑复杂性测度,并使用改测度作为指南来定义执行路径的基本集,从该基本集导出的测试用例保证对程序中的每一条执行语句至少执行一次。
对等区间划分是一种黑盒测试方法。对等区间划分是测试用例设计的非常形式化的方法。它将被测软件的输入输出划分成一些区间,被测软件对一个特定区间的任何值都是等价的。形成测试区间的数据不只是函数/过程的参数,也可以是软件可以访问的全局变量,系统资源等,这些变量或资源可以是以时间形式存在的数据,或以状态形式存在的输入输出序列。
对等区间划分假定位于单个区间的所有值对测试都是对等的,应该为每个区间的一个值设计一个测试用例。
对等区间划分基本上还是移植正面测试技术,需要使用负面测试进行补充。
对等区间划分的原则:
A.如果输入条件规定了取值范围,或者值的个数,则可以确定一个有效等价类和两个无效等价类;
B.如果输入条件规定了输入值的集合,或者是规定了“必须如何”的条件,这时可以确立一个有效等价类和一个无效等价类;
C.如果输入条件是一个布尔量,则可以确立一个有效等价类和一个无效等价类;
D.如果规定了输入数据的一组值,而且程序要对每一个输入值分别进行处理,这时要对每一个规定的输入值确立一个等价类,而对于这组值之外的所有值确立一个等价类;
E.如果规定了输入数据必须遵守的规则,则可以确立一个有效等件类(即遵守规则的数据)和若干无效等价类(从不同角度违反规则的数据);
F.如果确知以划分的等价类中的各元素在程序中的处理方式不同,则应进一步划分成更小的等价类。
边界值分析是一种黑盒测试方法。
边界值分析使用对等区间划分相同的分析。但是,边界值分析假定错误最有可能出现在区间之间的边界。边界值分析将一定程度的负面测试加入到测试设计中,期望错误会在区间边界发生,对边界值的两边都需设计测试用例。
选择测试用例的原则:
A.如果输入条件规定了值的范围,则应该取刚达到这个范围的边界值,以及刚刚超过这个范围边界的值作为测试输入数据;
B.如果输入条件规定了值的个数,则用最大个数、最小个数、比最大个数多1格、比最小个数少1个的数作为测试数据;
C.如果程序的规格说明给出的输入域或输出域是有序集合(如有序表、顺序文件等),则应选取集合的第一个和最后一个元素作为测试用例;
D.如果程序用了一个内部结构,应该选取这个内部数据结构的边界值作为测试用例;
E.分析规格说明,找出其他可能的边界条件。
状态转换测试对于软件被设计成一个状态机或实现了一种被建模成一种状态机的情况。可以设计测试用例测试状态间转换,测试用例创建引起转换的事件。
可以设计负面测试的测试用例用于测试状态与事件的非法组合。
在分支测试中,测试用例用于测试单元的控制流分支或决策点。通常用于实现决策覆盖(Decision Coverage)的测试目标。如果只有模块单元的函数功能设计说明,“黑盒”形式的分支测试对分支代码进行猜测,并设计测试用例执行该分支。如果拥有模块单元的结构设计说明,在单元中指明控制流,就可以设计测试用例执行各个分支。
Conditions Testing:测试程序模块中的所有逻辑条件,测试案例的设计策略包括:
A.Branch testing:执行每个分支至少一次;
B.Domain Testing:每个关系运算使用三个或四个测试;
C.Branch and relational operator testing:使用条件约束,覆盖约束集。
Data Flow Testing:根据变量定义和变量引用位置设置测试路径。
循环测试是一种白盒测试技术,注重于循环构造的有效性。
(1)简单循环:
下列测试集用于简单循环,其中n是允许通过循环的最大次数。
A.整个跳过循环;
B.只有一次通过循环;
C.两次通过循环;
D.m次通过循环,其中m<n;
E.n-1,n+1次通过循环。
(2)嵌套循环:
如果将简单循环的测试方法用于嵌套循环,可能的测试数就会随嵌套层数成几何级增加,这会导致不实际的测试数目,下面是一种减少测试数的方法:
A.从最内层循环开始,将其它循环设置为最小值;
B.对最内层循环使用简单循环,而使外层循环的跌代参数(即循环计数)最小,并为
范围外或排除的值增加其它测试;
C.由内向外构造下几个循环的测试,但其它的外层循环为最小值,并使其它的嵌套循
环为“典型”值;
D.继续直到测试所有的循环。
(3)串接循环:
如果串接循环的循环都彼此独立,可是使用嵌套的策略测试。但是如果两个循环串接起来,而第一个循环是第二个循环的初始值,则这两个循环并不是独立的。如果循环不独立,则推荐使用的嵌套循环的方法进行测试。
(4)无结构循环:
不能测试,尽量重新设计给结构化的程序结构后再进行测试。
在多数情况下,测试用例区间的边界值可以从模块单元的功能说明中获得,可以用上述方法进行对等区间划分。在某些情况下,模块单元的内部边界只能从模块的结构说明中获得,这就需要使用内部边界值分析方法进行对等区间划分。
错误猜测大多基于经验,需要从边界值分析等其他技术获得帮助。这种技术猜测特定软件类型可能发生的错误类型,并且设计测试用例查出这些错误。对有经验的工程师来说,错误猜测有时是唯一最有效发现BUG的测试设计方法。
为了最好地利用现成的经验,可以列出一个错误类型的检查列表,帮助猜测错误可能发生在单元中的位置,提高错误猜测的有效性。