|
初涉软件测试者可能认为拿到软件后就可以立即进行测试,并希望马上找出软件的所有缺陷,这种想法就如同没有受过工程训练的开发工程师急于去编写代码一样。软件测试也是一个工程,也需要按照工程的角度去认识软件测试,在具体的测试实施之前,我们需要明白我们测试什么,怎么测试等,也就是说通过制定测试用例指导测试的实施。
|
|
|
|
所谓的测试用例设计就是将软件测试的行为活动,作一个科学化的组织归纳。软件测试是有组织性、步骤性和计划性的,而设计软件测试用例的目的,就是为了能将软件测试的行为转换为可管理的模式。软件测试是软件质量管理中最实际的行动,同时也是耗时最多的一项。基于时间因素的考虑,软件测试行为必须能够加以量化,才能进一步让管理阶层掌握所需要的测试过程,而测试用例就是将测试行为具体量化的方法之一。
|
|
|
简单地说,测试用例就是设计一个情况,软件程序在这种情况下,必须能够正常运行并且达到程序所设计的执行结果。如果程序在这种情况下不能正常运行,而且这种问题会重复发生,那就表示软件程序人员已经测出软件有缺陷,这时候就必须将这个问题标示出来,并且输入到问题跟踪系统内,通知软件开发人员。软件开发人员接获通知后,将这个问题修改完成于下一个测试版本内,软件测试工程师取得新的测试版本后,必须利用同一个用例来测试这个问题,确保该问题已修改完成。
|
|
|
因为我们不可能进行穷举测试,为了节省时间和资源、提高测试效率,必须要从数量极大的可用测试数据中精心挑选出具有代表性或特殊性的测试数据来进行测试。
|
|
|
|
①在开始实施测试之前设计好测试用例,可以避免盲目测试并提高测试效率。
|
|
|
②测试用例的使用令软件测试的实施重点突出、目的明确。
|
|
|
③在软件版本更新后只需修正少部分的测试用例便可展开测试工作,降低工作强度,缩短项目周期。
|
|
|
④功能模块的通用化和复用化使软件易于开发,而测试用例的通用化和复用化则会使软件测试易于开展,并随着测试用例的不断精化其效率也不断攀升。
|
|
|
具体的黑盒测试用例设计方法包括等价类划分法、边界值分析法、错误推测法、因果图法、判定表驱动法、正交试验设计法、功能图法等。应该说,这些方法是比较实用的,但采用什么方法,在使用时自然要针对开发项目的特点对方法加以适当的选择。下面我们讨论几种常用的方法。
|
|
|
|
等价类划分是一种典型的黑盒测试方法,用这一方法设计测试用例完全不考虑程序的内部结构,只根据对程序的要求和说明,即需求规格说明书。我们必须仔细分析和推敲说明书的各项需求,特别是功能需求。把说明中对输入的要求和输出的要求区别开来并加以分解。
|
|
|
由于穷举测试工作量太大,以至于无法实际完成,促使我们在大量的可能数据中选取其中的一部分作为测试用例。例如,在不了解等价分配技术的前提下,我们做计算器程序的加法测试时,测试了1+1,1+2,1+3和1+4之后,还有必要测试1+5和1+6吗,能否放心地认为它们是正确的?我们感觉1+5和1+6,与前面的1+1,1+2都是很类似的简单加法。
|
|
|
等价类划分的办法是把程序的输入域划分成若干部分,然后从每个部分中选取少数代表性数据作为测试用例。每一类的代表性数据在测试中的作用等价于这一类中的其他值,也就是说,如果某一类中的一个例子发现了错误,这一等价类中的其他例子也能发现同样的错误;反之,如果某一类中的一个例子没有发现错误,则这一类中的其他例子也不会查出错误(除非等价类中的某些例子属于另一等价类,因为几个等价类是可能相交的)。使用这一方法设计测试用例,首先必须在分析需求规格说明的基础上划分等价类,列出等价类表。
|
|
|
|
等价类是指某个输入域的子集合。在该子集合中,各个输入数据对于揭露程序中的错误都是等效的。并合理地假定:测试某等价类的代表值就等于对这一类其他值的测试。
|
|
|
因此,可以把全部输入数据合理地划分为若干等价类,在每一个等价类中取一个数据作为测试的输入条件,就可以用少量代表性的测试数据取得较好的测试结果。等价类划分有两种不同的情况:有效等价类和无效等价类。
|
|
|
有效等价类:指对于程序的规格说明来说是合理的、有意义的输入数据构成的集合。利用有效等价类可检验程序是否实现了规格说明中所规定的功能和性能。
|
|
|
|
设计测试用例时,要同时考虑这两种等价类。因为软件不仅要能接收合理的数据,也要能经受意外的考验。这样的测试才能确保软件具有更高的可靠性。
|
|
|
|
①在输入条件规定了取值范围或值的个数的情况下,可以确立一个有效等价类和两个无效等价类。
|
|
|
②在输入条件规定了输入值的集合或者规定了“必须如何”的条件的情况下,可以确立一个有效等价类和一个无效等价类。
|
|
|
③在输入条件是一个布尔量的情况下,可确定一个有效等价类和一个无效等价类。
|
|
|
④在规定了输入数据的一组值(假定n个),并且程序要对每一个输入值分别处理的情况下,可确立n个有效等价类和一个无效等价类。
|
|
|
⑤在规定了输入数据必须遵守的规则的情况下,可确立一个有效等价类(符合规则)和若干个无效等价类(从不同角度违反规则)。
|
|
|
⑥在确知已划分的等价类中,各元素在程序处理中的方式不同的情况下,则应再将该等价类进一步地划分为更小的等价类。
|
|
|
在确立了等价类之后,建立等价类表,列出所有划分出的等价类如下表所示。
|
|
|
|
|
|
|
|
②设计一个新的测试用例,使其尽可能多地覆盖尚未覆盖的有效等价类。重复这一步,最后使得所有有效等价类均被测试用例所覆盖。
|
|
|
③设计一个新的测试用例,使其只覆盖一个无效等价类。重复这一步使所有无效等价类均被覆盖。
|
|
|
在寻找等价区间时,想办法把软件的相似输入、输出、操作分成组。这些组就是等价区间。请看一些例子。
|
|
|
在两数相加用例中,测试1+13和1+99999999似乎有点不同。这是一种直觉,一个是普通加法,而另一个似乎有些特殊,这个直觉是对的。程序对1和最大数值相加的处理和对两个小一些的数值相加的处理有所不同。后者必须处理溢出情况。因为软件操作可能不同,所以这两个用例属于不同的等价区间。
|
|
|
如果具有编程经验,就可能会想到更多可能导致软件操作不同的“特殊”数值。如果不是程序员,也不用担心,你很快就会学到这种技术,无须了解代码细节就可以运用。
|
|
|
如下图所示是复制的多种方法,给出了选中编辑菜单后显示复制和粘贴命令的计算器程序。每一项功能(即复制和粘贴)有5种执行方式。要想复制,可以单击复制菜单命令,键入C,按Ctrl+C或Ctrl+Shift+C组合键。任何一种输入途径都会把当前数值复制到剪贴板中,一一执行同样的输出操作,产生同样的结果。
|
|
|
|
|
如果要测试复制命令,可以把这5种输入途径划分减为3个,单击菜单命令,键入C和按Ctrl+C组合键。对软件质量有了信心之后,知道无论以何种方式激活复制功能都工作正常,甚至可以进一步缩减为1个区间,例如按Ctrl+C组合键。
|
|
|
再看下一个例子。看一下在标准的另存为对话框(如下图所示)中输入文件名称的情形。
|
|
|
|
|
Windows文件名可以包含除了“、”、“/”、“:”、“.”、“?”、“<>”和“\”之外的任意字符。文件名长度是1~255个字符。如果为文件名创建测试用例,等价区间有合法字符、非法字符、合法长度的名称、过长名称和过短名称。
|
|
|
例题:根据下面给出的规格说明,利用等价类划分的方法,给出足够的测试用例。“一个程序读入3个整数,把这3个数值看作一个三角形的3条边的长度值。这个程序要打印出信息,说明这个三角形是不等边的、是等腰的、还是等边的”。
|
|
|
我们可以设三角形的3条边分别为A, B, C。如果它们能够构成三角形的3条边,必须满足:
|
|
|
A>0,B>0,C>0,且A+B>C, B+C>A, A+C>B。
|
|
|
如果是等腰的,还要判断A=B,或B=C,或A=C。
|
|
|
如果是等边的,则需判断是否A=B,且B=C,且A=C。
|
|
|
|
|
|
设计测试用例:输入顺序是【A, B, C】,如下表所示。
|
|
|
|
|
请记住,等价分配的目标是把可能的测试用例组合缩减到仍然足以满足软件测试需求为止。因为,选择了不完全测试,就要冒一定的风险,所以必须仔细选择分类。
|
|
|
关于等价分配最后要讲的一点是,这样做有可能不客观。科学有时也是一门艺术。测试同一个复杂程序的两个软件测试员,可能会制定出两组不同的等价区间。只要审查等价区间的人都认为它们足以覆盖测试对象就可以了。
|
|
|
|
人们从长期的测试工作经验得知,大量的错误是发生在输入或输出范围的边界上的,而不是在输入范围的内部。因此针对各种边界情况设计测试用例,可以查出更多的错误。例如,在做三角形计算时,要输入三角形的3个边长A、B和C。这3个数值应当满足A>0、B>0、C>0、A+B>C、A+C>B、B+C>A,才能构成三角形。但如果把6个不等式中的任何一个大于号“>”错写成大于等于号“≥”,那就不能构成三角形。问题恰恰出现在容易被疏忽的边界附近。这里所说的边界是指相当于输入等价类和输出等价类而言,稍高于其边界值及稍低于其边界值的一些特定情况。
|
|
|
|
我们可以想象一下,如果在悬崖峭壁边可以自信地安全行走,平地就不在话下了。如果软件在能力达到极限时能够运行,那么在正常情况下一般也就不会有什么问题。
|
|
|
边界条件是特殊情况,因为编程从根本上说不怀疑边界有问题。奇怪的是,程序在处理大量中间数值时都是对的,但是可能在边界处出现错误。下面的一段源代码说明了在一个极简单的程序中是如何产生边界条件问题的。
|
|
|
|
这段代码的意图是创建包含10个元素的数组,并为数组中的每一个元素赋初值-1。看起来相当简单。它建立了包含10个整数的数组data和一个计数值i。For循环是从1~10,数组中从第1个元素到第10个元素被赋予数值-1。那么边界问题在哪儿呢?
|
|
|
在大多数开发语言脚本中,应当以声明的范围定义数组,在本例中定义语句是dim data(10)as interger,第一个创建的元素是data(0),而不是data(1)。该程序实际上创建了一个从data(0)~data(10)共11个元素的数组。程序从1~10循环将数组元素的值初始化为-1,但是由于数组的第一个元素是data(0),因此它没有被初始化。程序执行完毕,数组值如下:
|
|
|
|
注意data(0)的值是0,而不是-1。如果这位程序员以后忘记了,或者其他程序员不知道这个数据数组是如何初始化的,那么他就可能会用到数组的第1个元素data(0),以为它的值是-1。诸如此类的问题很常见,在复杂的大型软件中,可能导致极其严重的软件缺陷。
|
|
|
|
上面讨论的普通边界条件是最容易找到的。它们在产品说明书中有定义,或者在使用软件的过程中确定。而有些边界在软件内部,最终用户几乎看不到,但是软件测试仍有必要检查。这样的边界条件称为次边界条件或者内部边界条件。
|
|
|
寻找这样的边界不要求软件测试员具有程序员那样阅读源代码的能力,但是要求大体了解软件的工作方式。2的乘方和ASCII表就是这样的例子。
|
|
|
|
计算机和软件的计数基础是二进制数,用位(bit)来表示0和1,一个字节(byte)由8位组成,一个字(word)由两个字节组成等。下表中列出了常用的2的乘方单位及其范围或值。
|
|
|
|
|
上表中所列的范围和值是作为边界条件的重要数据。除非软件向用户提出这些范围,否则在需求文档中不会指明。然而,它们通常由软件内部使用,外部是看不见的,当然,在产生软件缺陷的情况下可能会看到。
|
|
|
在建立等价区间时,要考虑是否需要包含2的乘方边界条件。例如,如果软件接受用户输入1~1000范围内的数字,谁都知道在合法区间中包含1和1000,也许还要有2和999。为了覆盖任何可能的2的乘方次边界,还要包含临近双位边界的14、15和16,以及临近字节边界的254、255和256。
|
|
|
|
另一个常见的次边界条件是ASCII字符表。如下表所示是部分ASCII值表的清单。
|
|
|
|
|
注意,上表不是结构良好的连续表。0~9的后面ASCII值是48~57。斜杠字符(/)在数字0的前面,而冒号字符“:”在数字9的后面。大写字母A~Z对应65~90。小写字母对应97~122。这些情况都代表次边界条件。
|
|
|
如果测试进行文本输入或文本转换的软件,在定义数据区间包含哪些值时,参考一下ASCII表是相当明智的。例如,如果测试的文本框只接受用户输入字符A~Z和a~z,就应该在非法区间中包含ASCII表中这些字符前后的值@、[、和{。
|
|
|
|
另一种看起来很明显的软件缺陷来源是当软件要求输入时(比如在文本框中),不是没有输入正确的信息,而是根本没有输入任何内容,只按了Enter键。这种情况在产品说明书中常常被忽视,程序员也可能经常遗忘,但是在实际使用中却时有发生。程序员总会习惯性地认为用户要么输入信息,不管是看起来合法的或非法的信息,要么就会选择Cancel键放弃输入,如果没有对空值进行好的处理的话,恐怕程序员自己都不知道程序会引向何方。
|
|
|
正确的软件通常应该将输入内容默认为合法边界内的最小值,或者合法区间内的某个合理值,否则,返回错误提示信息。
|
|
|
因为这些值通常在软件中进行特殊处理,所以不要把它们与合法情况和非法情况混在一起,而要建立单独的等价区间。
|
|
|
|
边界值分析是一种补充等价划分的测试用例设计技术,它不是选择等价类的任意元素,而是选择等价类边界的测试用例。实践证明,为检验边界附近的处理专门设计测试用例,常常取得良好的测试效果。边界值分析法不仅重视输入条件边界,而且也适用于输出域测试用例。
|
|
|
|
①如果输入条件规定了值的范围,则应取刚达到这个范围的边界的值,以及刚刚超越这个范围边界的值作为测试输入数据。
|
|
|
②如果输入条件规定了值的个数,则用最大个数、最小个数、比最小个数少1、比最大个数多1的数作为测试数据。
|
|
|
|
|
⑤如果程序的规格说明给出的输入域或输出域是有序集合,则应选取集合的第一个元素和最后一个元素作为测试用例。
|
|
|
⑥如果程序中使用了一个内部数据结构,则应当选择这个内部数据结构边界上的值作为测试用例。
|
|
|
|
|
错误推测法就是基于经验和直觉推测程序中所有可能存在的各种错误,有针对性地设计测试用例的方法。
|
|
|
错误推测法的基本思想是列举出程序中所有可能有的错误和容易发生错误的特殊情况,根据它们选择测试用例。例如,设计一些非法、错误、不正确和垃圾数据进行输入测试是很有意义的。如果软件要求输入数字,就输入字母。如果软件只接受正数,就输入负数。如果软件对时间敏感,就看它在公元3000年是否还能正常工作。还有,例如,在单元测试时曾列出的许多在模块中常见的错误,以前产品测试中曾经发现的错误等,这些就是经验的总结。另外,输入数据和输出数据为0的情况,或者输入表格为空格或输入表格只有一行,这些都是容易发生错误的情况。可选择这些情况下的例子作为测试用例。
|
|
|
|
前节介绍的等价类划分方法和边界值分析法都是着重考虑输入条件,并没有考虑到输入情况的各种组合,也没考虑到各个输入情况之间的相互制约关系。如果在测试时必须考虑输入条件的各种组合,可能的组合数将是天文数字。因此必须考虑描述多种条件的组合,相应地产生多个动作的形式来考虑设计测试用例,这就需要利用因果图。在软件工程中,有些程序的功能可以用判定表的形式来表示,并根据输入条件的组合情况规定相应的操作。很自然,应该为判定表中的每一列设计一个测试用例,以便保证测试程序在输入条件的某种组合下,操作是正确的。
|
|
|
|
因果图法是从用自然语言书写的程序规格说明的描述中找出因(输入条件)和果(输出或程序状态的改变),通过因果图转换为判定表。
|
|
|
|
①分析程序规格说明的描述中,哪些是原因,哪些是结果。原因常常是输入条件或是输入条件的等价类,而结果是输出条件。
|
|
|
②分析程序规格说明的描述中语义的内容,并将其表示成连接各个原因与各个结果的“因果图”。
|
|
|
③标明约束条件。由于语法或环境的限制,有些原因和结果的组合情况是不可能出现的。为表明这些特定的情况,在因果图上使用若干个标准的符号标明约束条件。
|
|
|
|
|
因果图生成的测试用例(局部,组合关系下的)包括了所有输入数据的取TRUE与取FALSE的情况,构成的测试用例数目达到最少,且测试用例数目随输入数据数目的增加而增加。
|
|
|
事实上,在较为复杂的问题中,这个方法常常是十分有效的,它能有力地帮助我们确定测试用例。当然,如果哪个开发项目在设计阶段就采用了判定表,也就不必再画因果图了,而是可以直接利用判定表设计测试用例了。
|
|
|
通常在因果图中,用Ci表示原因,Ei表示结果,其基本符号如下图所示。各结点表示状态,可取“0”或“1”值。“0”表示某状态不出现,“1”表示某状态出现。
|
|
|
|
|
①恒等:若原因出现,则结果出现;若原因不出现,则结果也不出现。
|
|
|
②非(~):若原因出现,则结果不出现;若原因不出现,则结果出现。
|
|
|
③或(∨):若几个原因中有1个出现,则结果出现;若几个原因都不出现,则结果不出现。
|
|
|
④与(∧):若几个原因都出现,结果才出现。若其中有1个原因不出现,则结果不出现。
|
|
|
为了表示原因与原因之间、结果与结果之间可能存在的约束条件,在因果图中可以附加一些表示约束条件的符号。从输入(原因)考虑,有4种约束,例如:(a)、(b)、(c)、(d)。从输出(结果)考虑,还有1种约束,例如:(e),如下图所示。
|
|
|
|
|
①E(互斥):表示a、b两个原因不会同时成立,两个中最多有一个可能成立。
|
|
|
②I(包含):表示a、b、c这3个原因中至少有一个必须成立。
|
|
|
③O(惟一):表示a和b当中必须有一个,且仅有一个成立。
|
|
|
④R(要求):表示当a出现时,b必须也出现。a出现时不可能b不出现。
|
|
|
⑤M(屏蔽):表示当a是1时,b必须是0。而当a为0时,b的值不定。
|
|
|
|
例如:有一个处理单价为1元5角钱的盒装饮料的自动售货机软件。若投入1元5角硬币,按下“可乐”、“雪碧”或“红茶”按钮,相应的饮料就送出来。若投入的是两元硬币,在送出饮料的同时退还5角硬币。
|
|
|
|
|
③按“可乐”按钮;④按“雪碧”按钮;⑤按“红茶”按钮。
|
|
|
|
|
|
根据原因和结果,我们可以设计这样一个因果图(如下图所示。)
|
|
|
|
|
转换为测试用例,如下表所示,每一列可作为确定测试用例的依据。
|
|
|
|
|
|
前面因果图方法中已经用到了判定表。判定表是分析和表达多逻辑条件下执行不同操作的情况的工具。在程序设计发展的初期,判定表就已被用作编写程序的辅助工具了。它可以把复杂的逻辑关系和多种条件组合的情况表达得较明确。
|
|
|
|
|
|
|
. 条件桩(condition stub):列出了问题的所有条件。通常认为列出的条件的次序无关紧要。
|
|
|
. 动作桩(action stub):列出了问题规定可能采取的操作。这些操作的排列顺序没有约束。
|
|
|
. 条件项(condition entry):列出针对它所列条件的取值,在所有可能情况下的真假值。
|
|
|
. 动作项(action entry):列出在条件项的各种取值情况下应该采取的动作。
|
|
|
. 规则:任何一个条件组合的特定取值及其相应要执行的操作。在判定表中贯穿条件项和动作项的一列就是一条规则。显然,判定表中列出多少组条件取值,也就有多少条规则,条件项和动作项就有多少列。
|
|
|
|
|
①确定规则的个数。假如有n个条件,每个条件有两个取值(0,1),故有2n种规则。
|
|
|
|
|
|
|
Beizer指出了适合使用判定表设计测试用例的条件:
|
|
|
①规格说明以判定表的形式给出,或很容易转换成判定表。
|
|
|
|
|
④当某一规则的条件已经满足,并确定要执行的操作后,不必检验别的规则。
|
|
|
⑤如果某一规则要执行多个操作,这些操作的执行顺序无关紧要。
|
|
|
|
利用因果图来设计测试用例时,作为输入条件的原因与输出结果之间的因果关系,有时很难从软件需求规格说明中得到。往往因果关系非常庞大,导致利用因果图而得到的测试用例数目多得惊人,给软件测试带来沉重的负担。为了有效地、合理地减少测试的工时与费用,可利用正交试验法进行测试用例的设计。
|
|
|
|
依据Galois理论,正交试验设计方法是从大量的试验数据中挑选适量的、有代表性的点,从而合理地安排测试的一种科学的试验设计方法。
|
|
|
正交试验法,就是使用已经造好了的表格“——”正交表来安排试验并进行数据分析的一种方法。它简单易行并且计算表格化,应用性较好。下边通过一个例子来说明正交试验法。
|
|
|
例题:为提高某化工产品的转化率,选择了三个有关因素进行条件试验,反应温度(A),反应时间(B),用碱量(C),并确定了它们的试验范围如下。
|
|
|
|
|
|
试验目的是搞清楚因子A、B、C对转化率有什么影响,哪些是主要的,哪些是次要的,从而确定最适生产条件,即温度、时间及用碱量各为多少才能使转化率最高。这里,对因子A、B和C,在试验范围内都选了三个水平,如下所示。
|
|
|
. A:A1=80℃,A2=85℃,A3=90℃;
|
|
|
. B:B1=90分钟,B2=120分钟,B3=150分钟;
|
|
|
|
当然,在正交试验设计中,因子可以是定量的,也可以是定性的。而定量因子各水平间的距离可以相等,也可以不相等。这个三因子三水平的条件试验,通常有两种试验方法:
|
|
|
①取三因子所有水平之间的组合,即A1B1C1,A1B1C2,A1B2C1,……,A3B3C3,共有33=27次试验。用下图表示立方体的27个节点。这种试验法叫做全面试验法。
|
|
|
|
|
全面试验对各因子与指标间的关系剖析得比较清楚。但试验次数太多。特别是当因子数目多,每个因子的水平数目也很多时,试验量非常大。如选6个因子,每个因子取5个水平时,如欲做全面试验,则需56=15625次试验,这实际上是不可能实现的。如果应用将要介绍的正交试验法,只做25次试验就行了。而且在某种意义上讲,这25次试验代表了15625次试验。
|
|
|
②简单对比法,即变化一个因素而固定其他因素,如首先固定B、C于Bl、Cl,使A变化:
|
|
|
|
如得出结果A3最好,则固定A于A3,C还是Cl,使B变化:
|
|
|
|
得出结果以B2为最好,则固定B于B2,A于A3,使C变化:
|
|
|
|
试验结果以C2为最好。于是就认为最好的工艺条件是A3B2C2。
|
|
|
这种方法一般也有一定的效果,但缺点很多。首先这种方法的选点代表性很差,如按上述方法进行试验,试验点完全分布在一个角上,而在一个很大的范围内没有选点,因此这种试验方法不全面,所选的工艺条件A3B2C2不一定是27个组合中最好的。其次,用这种方法比较条件好坏时,是把单个的试验数据拿来,进行数值上的简单比较,而试验数据中必然包含着误差成分,所以单个数据的简单比较不能剔除误差,必然造成结论的不稳定。
|
|
|
简单对比法的最大优点就是试验次数少,例如,6因子5水平试验,在不重复时,只用5+(6-1)×(5-1)=5+5×4=25次试验就可以了。
|
|
|
考虑兼顾这两种试验方法的优点,从全面试验的点中选择具有典型性、代表性的点,使试验点在试验范围内分布得很均匀,能反映全面情况。但我们又希望试验点尽量地少,为此还要具体考虑一些问题。如上例,对应于A有A1、A2、A3 3个平面,对应于B、C也各有3个平面,共9个平面。则这9个平面上的试验点都应当一样多,即对每个因子的每个水平都要同等看待。具体来说,每个平面上都有3行、3列,要求在每行、每列上的点一样多。这样,作出如下图所示的设计,试验点用⊙表示。我们看到,在9个平面中每个平面上都恰好有3个点,而每个平面的每行每列都有1个点,而且只有1个点,总共9个点。这样的试验方案,试验点的分布很均匀,试验次数也不多。
|
|
|
|
|
当因子数和水平数都不太大时,尚可通过作图的办法来选择分布很均匀的试验点。但是因子数和水平数多了,作图的方法就不行了。试验工作者在长期的工作中总结出一套办法,创造出所谓的正交表。按照正交表来安排试验,既能使试验点分布得很均匀,又能减少试验次数,而且计算分析简单,能够清晰地阐明试验条件与指标之间的关系。用正交表来安排试验及分析试验结果,这种方法叫正交试验设计法。
|
|
|
一般用L代表正交表,常用的有L8(27)、L9(34)、L16(45)、L8(4×24)等。此符号各数字的意义如下。
|
|
|
例如:L8(27),其中,7为此表列的数目(最多可安排的因子数);2为因子的水平数;8为此表行的数目(试验次数)。
|
|
|
又例如:L18(2×37),有7列是3水平的,有1列是2水平的,L18(2×37)的数字告诉我们,用它来安排试验,做18个试验最多可以考察1个2水平因子和7个3水平因子。
|
|
|
在行数为mn型的正交表中(m, n是正整数),试验次数(行数)=Σ(每列水平数-1)+1,如L8(27),8=7×(2-1)+1,利用上述关系式可以从所要考察的因子水平数来决定最低的试验次数,进而选择合适的正交表。比如要考察5个3水平因子及一个2水平因子,则起码的试验次数为5×(3-1)+1×(2-1)+1=12(次),这就是说,要在行数不小于12,既有2水平列又有3水平列的正交表中选择,L18(2×37)适合。正交表具有两条性质:每一列中各数字出现的次数都一样多;任何两列所构成的各有序数对出现的次数都一样多。所以称之为正交表。
|
|
|
例如,在L9(34)中(如下表所示),各列中的1、2、3都各自出现3次;任何两列,例如第3、4列,所构成的有序数对从上向下共有9种,既没有重复也没有遗漏。其他任何两列所构成的有序数对也是这9种各出现一次。这反映了试验点分布的均匀性。
|
|
|
|
|
试验方案应该如何设计呢?安排试验时,只要把所考察的每一个因子任意地对应于正交表的一列(一个因子对应一列,不能让两个因子对应同一列),然后把每列的数字“翻译”成所对应因子的水平。这样,每一行的各水平组合就构成了一个试验条件(不考虑没安排因子的列)。对于上例,因子A、B、C都是3水平的,试验次数要不少于3×(3-1)+1=7(次),可考虑选用L9(34)。因子A、B、C可任意地对应于L9(34)的某三列,例如A、B、C分别放在1、2、3列,然后试验按行进行,顺序不限,每一行中各因素的水平组合就是每一次的试验条件,从上到下就是这个正交试验的方案,如下表所示。这个试验方案的几何解释正好是正交试验设计图例。
|
|
|
|
|
3个3水平的因子,做全面试验需要33=27次试验,现用L9(34)来设计试验方案,只要做9次,工作量减少了2/3,而在一定意义上代表了27次试验。
|
|
|
|
|
. 提取功能说明,构造因子“——”状态表。把影响实验指标的条件称为因子,而影响实验因子的条件叫做因子的状态。利用正交试验设计方法来设计测试用例时,首先要根据被测试软件的规格说明书找出影响其功能实现的操作对象和外部因素,把它们当作因子,而把各个因子的取值当做状态。对软件需求规格说明中的功能要求进行划分,把整体的、概要性的功能要求进行层层分解与展开,分解成具体的、有相对独立性的基本的功能要求。这样就可以把被测试软件中所有的因子都确定下来,并为确定因子的权值提供参考的依据。确定因子与状态是设计测试用例的关键。因此,要求尽可能全面地、正确地确定取值,以确保测试用例的设计做到完整与有效。
|
|
|
. 加权筛选,生成因素分析表。对因子与状态的选择可按其重要程度分别加权。可根据各个因子及状态作用的大小、出现频率的大小以及测试的需要,确定权值的大小。
|
|
|
. 利用正交表构造测试数据集,正交表的推导依据Galois理论。
|
|
|
利用正交试验设计方法设计测试用例,与使用等价类划分、边界值分析、因果图等方法相比,有以下优点:节省测试工作工时;可控制生成的测试用例的数量;测试用例具有一定的覆盖率。
|
|
|
正交试验法在软件测试中是一种有效的方法,例如在平台参数配置方面,我们要选择哪种组合方式是最好的,每个参数可能就是一个因子,参数的不同取值就是水平,这样我们可以采用正交试验法设计出最少的测试组合,达到有效的测试目的。
|
|
|
|
一个程序的功能说明通常由动态说明和静态说明组成。动态说明描述了输入数据的次序或转移的次序。静态说明描述了输入条件与输出条件之间的对应关系。对于较复杂的程序,由于存在大量的组合情况,因此,仅用静态说明组成的规格说明对于测试来说往往是不够的,必须用动态说明来补充功能说明。
|
|
|
|
功能图方法是用功能图形象地表示程序的功能说明,并机械地生成功能图的测试用例。功能图模型由状态迁移图和逻辑功能模型构成。
|
|
|
. 状态迁移图用于表示输入数据序列以及相应的输出数据。在状态迁移图中,由输入数据和当前状态决定输出数据和后续状态。
|
|
|
. 逻辑功能模型用于表示在状态中输入条件和输出条件之间的对应关系。逻辑功能模型只适合于描述静态说明,输出数据仅由输入数据决定。测试用例则是由测试中经过的一系列状态和在每个状态中必须依靠输入/输出数据满足的一对条件组成。
|
|
|
功能图方法实际上是一种黑盒、白盒混合用例设计方法。
|
|
|
功能图方法中要用到逻辑覆盖和路径测试的概念和方法,属白盒测试方法中的内容。逻辑覆盖是以程序内部的逻辑结构为基础的测试用例设计方法,该方法要求测试人员对程序的逻辑结构有清楚的了解。由于覆盖测试的目标不同,逻辑覆盖可分为:语句覆盖、判定覆盖、判定-条件覆盖,条件组合覆盖及路径覆盖。下面我们指的逻辑覆盖和路径是功能或系统水平上的,以区别于白盒测试中的程序内部的,如下图及下表所示。
|
|
|
|
|
|
|
|
|
功能图由状态迁移图和布尔函数组成。状态迁移图用状态和迁移来描述一个状态,指出数据输入的位置(或时间),而迁移则指明状态的改变,同时要依靠判定表和因果图表示的逻辑功能。
|
|
|
采用什么样的方法生成测试用例?从功能图生成测试用例,得到的测试用例数是可接受的。问题的关键是如何从状态迁移图中选取测试用例。若用节点代替状态,用弧线代替迁移,状态迁移图就可转化成一个程序的控制流程图形式。问题就转化为程序的路径测试问题(白盒测试范畴概念)了。
|
|
|
测试用例生成规则:为了把状态迁移(测试路径)的测试用例与逻辑模型的测试用例组合起来,从功能图生成实用的测试用例,需定义下面的规则。一个结构化的状态迁移中,定义3种形式的循环:顺序、选择和重复。但分辨一个状态迁移中的所有循环是有困难的。
|
|
|
|
. 生成局部测试用例:在每个状态中,从因果图生成局部测试用例。局部测试库由原因值(输入数据)组合与对应的结果值(输出数据或状态)构成。
|
|
|
. 测试路径生成:利用上面的规则生成从初始状态到最后状态的测试路径。
|
|
|
. 测试用例合成:合成测试路径与功能图中每个状态的局部测试用例。结果是视状态到最后状态的一个状态序列,以及每个状态中输入数据与对应输出数据组合。
|
|
|
|
|
现在的软件几乎都是用事件触发来控制流程的,事件触发时的情景便形成了场景,而同一事件不同的触发顺序和处理结果就形成事件流。这种在软件设计方面的思想也可引入到软件测试中,可以比较生动地描绘出事件触发时的情景,有利于测试设计者设计测试用例,同时使测试用例更容易理解和执行。
|
|
|
提出这种测试思想的是Rational公司,并在RUP2000中文版中有详尽的解释和应用。
|
|
|
用例场景用来描述流经用例的路径,从用例开始到结束遍历这条路径上所有基本流和备选流。
|
|
|
|
如下图所示,图中经过用例的每条路径都用基本流和备选流来表示,直黑线表示基本流,是经过用例的最简单的路径。备选流用不同的彩色表示,一个备选流可能从基本流开始,在某个特定条件下执行,然后重新加入基本流中(如备选流1和3);也可能起源于另一个备选流(如备选流2),或者终止用例而不再重新加入到某个流(如备选流2和4)。
|
|
|
按照如下图中所示的每个经过用例的路径,可以确定以下不同的用例场景。
|
|
|
|
|
|
|
|
|
|
|
|
|
注:为方便起见,场景5、6和8只考虑了备选流3循环执行一次的情况。
|
|
|
需要说明的是,为了能清晰地说明场景,我们所举的例子都非常简单,在实际应用中,测试用例很少如此简单。
|
|
|
|
|
|
|
|
如下表所示,包含了如上图中所示提款用例的基本流和某些备用流。
|
|
|
|
|
|
|
|
|
|
注:为方便起见,备选流3和6(场景3和7)内的循环以及循环组合未纳入表中。
|
|
|
|
对于这7个场景中的每一个场景都需要确定测试用例,一般采用矩阵或决策表来确定和管理测试用例。如下表所示是一种通用格式,其中行代表各个测试用例,列代表测试用例的信息。本例中的测试用例包含测试用例ID、场景/条件、测试用例中涉及的所有数据元素和预期结果等项目。首先确定执行用例场景所需的数据元素,然后构建矩阵,最后要确定包含执行场景所需的适当条件的测试用例。在下面的矩阵中,V表示这个条件必须是有效的才可执行基本流,I表示这种条件下将激活所需备选流,n/a表示这个条件不适用于测试用例。
|
|
|
|
|
在上面的矩阵中,六个测试用例执行了四个场景。对于基本流,上述测试用例CW1被称为正面测试用例。它一直沿着用例的基本流路径执行,未发生任何偏差。基本流的全面测试必须包括负面测试用例,以确保只有在符合条件的情况下才执行基本流。这些负面测试用例由CW2~CW6表示。虽然CW2~CW6相对于基本流而言都是负面测试用例,但它们相对于备选流2~4而言是正面测试用例。而且对于这些备选流中的每一个而言,至少存在一个负面测试用例,就是CW1-基本流。
|
|
|
每个场景只有一个正面测试用例和负面测试用例是不充分的,场景4正是这样的一个示例。要全面地测试场景4-PIN有误,至少需要三个正面测试用例,以激活场景4:
|
|
|
①输入了错误的PIN,但仍存在输入机会,此备选流重新加入基本流中的步骤3-输入PIN。
|
|
|
②输入了错误的PIN,而且不再有输入机会,则此备选流将保留银行卡并终止用例。
|
|
|
③最后一次输入时输入了“正确”的PIN。备选流在步骤5-输入金额处重新加入基本流。
|
|
|
注意,在上面的矩阵中,无需为条件输入任何实际的值。以这种方式创建测试用例矩阵的一个优点在于容易看到测试的是什么条件。由于只需要查看V和I,这种方式还易于判断是否已经确定了充足的测试用例。从上表中可发现存在几个无效的条件I,这表明测试用例还不完全,如场景6-不存在的账户/账户类型有误和场景7-账户余额不足就缺少测试用例。
|
|
|
|
一旦确定了所有的测试用例,则应对这些用例进行复审和验证以确保其准确且适度,并取消多余或等效的测试用例。
|
|
|
|
|
测试用例一经认可,就可以确定实际数据值(在测试用例实施矩阵中)并且设定测试数据。
|
|
|
以上测试用例只是在本次迭代中需要用来验证提款用例的一部分测试用例。需要的其他测试用例包括以下内容。
|
|
|
场景6——账户不存在/账户类型有误:未找到账户或账户不可用;
|
|
|
场景6——账户不存在/账户类型有误:禁止从该账户中提款;
|
|
|
|
在将来的迭代中,当实施其他事件流时,在下列情况下将需要测试用例:
|
|
|
①无效卡(所持卡为挂失卡、被盗卡、非承兑银行发卡、磁条损坏等);
|
|
|
|
|
④ATM内的现金不足或不能提供所请求的金额(与CW3不同,在CW3中只是一种币值不足,而不是所有币值都不足);
|
|
|
|
|
结论:所有从事软件测试和即将从事软件测试的人大都是从黑盒测试做起的,每种类型的软件有各自的特点,每种测试用例设计的方法也有各自的特点,针对不同软件如何利用这些黑盒方法是非常重要的,它能极大地提高测试效率和测试覆盖度,认真掌握这些方法的原理,有效提高测试水平,积累更多的测试经验,这是测试人员最宝贵的财富。
|
|
|
|
测试用例的设计方法不是单独存在的,具体到每个测试项目里都会用到多种方法,每种类型的软件有各自的特点,每种测试用例设计的方法也有各自的特点,针对不同软件如何利用这些黑盒方法是非常重要的,在实际测试中,往往是综合使用各种方法才能有效地提高测试效率和测试覆盖度,这就需要认真掌握这些方法的原理,积累更多的测试经验,以有效地提高测试水平。
|
|
|
以下是各种测试方法选择的综合策略,可供读者在实际应用过程中参考。
|
|
|
①首先进行等价类划分,包括输入条件和输出条件的等价划分,将无限测试变成有限测试,这是减少工作量和提高测试效率最有效的方法。
|
|
|
②在任何情况下都必须使用边界值分析方法。经验表明,用这种方法设计出的测试用例发现程序错误的能力最强。
|
|
|
③可以用错误推测法追加一些测试用例,这需要依靠测试工程师的智慧和经验。
|
|
|
④对照程序逻辑,检查已设计出的测试用例的逻辑覆盖程度。如果没有达到要求的覆盖标准,应当再补充足够的测试用例。
|
|
|
⑤如果程序的功能说明中含有输入条件的组合情况,则一开始就可选用因果图法和判定表驱动法。
|
|
|
⑥对于参数配置类的软件,要用正交试验法选择较少的组合方式达到最佳效果。
|
|
|
⑦功能图法也是很好的测试用例设计方法,我们可以通过不同时期条件的有效性设计不同的测试数据。
|
|
|
⑧对于业务流清晰的系统,可以利用场景法贯穿整个测试案例过程,在案例中综合使用各种测试方法。
|
|
|