软件测试的艺术
总之,测试,这是一个相对比较开发来讲门槛不算太高的职业(当然要做到精深未必容易,甚至难度还要高),而且收入还算不错。
有一条典型的编程项目中,软件测试或系统测试大约占用50%的项目时间和超过50%的总成本。软件测试依然是软件开发中的“黑色艺术”
软件的普遍应用提升了测试的意义
所谓软件测试,就是一个过程或一系列过程,用来确认计算机代码完成了其应该完成的功能,不执行其不该有的操作。
通过测试来增加程序的价值,是指测试提高了程序的可靠性或质量,提高了程序的可靠性,是指找出并最终修改了程序的错误。
定义:测试是为发现错误而执行程序的过程。
心理学研究表明,当人们开始一项工作时,如果已经知道它时不可行的或无法实现时,人们的表现就会相当糟糕。
黑盒测试是一种重要的城市策略,又称为数据驱动的测试或输入/输出驱动的测试,就是将程序视为一个黑盒子,
测试目标与程序的内部机制和结构完全无关,而是讲重点放在发现程序不按其规范正确运行的环境条件。(穷举输入测试)
白盒测试或称为逻辑驱动的测试,允许我们检查程序的内部结构,这种测试策略对程序的逻辑结构进行检查,
从中获取测试数据(遗憾的是,常常忽略了程序的规范)(穷举路径测试)
尽管穷举输入测试要强于穷举路径测试,但两者都不是有效的方法,因为这两种方法都不可行。
软件测试的重要原则:
- u 测试用例中一个必需部分是对预期输出或结果进行定义。
- u 程序员应对避免测试自己编写的程序、
- u 编写软件的组织不应当测试自己编写的软件
- u 应当彻底检查每个测试的执行结果
- u 测试用例的编写不仅应当根据有效和预料的输入情况,而且也应当根据和未预料到的输入情况。
- u 检查程序是否“未做其应该做的”仅是测试的一半,测试的另一半是检查程序“是否做了其不应该做的”
- u 应避免测试用例用后即弃,除非软件本身就是一个一次性的软件
- u 计划测试工作时不应默许假定不会发现错误
- u 程序某部分存在更多错误的可能性,与该部分已发现错误的数量成正比
- u 软件测试是一项极富创造性、极具智力挑战性的工作
人们必须已经形成了特定的认识。没有期望,也就没有所谓的意外
小结欸v
- 软件测试是为发现错误而执行程序的过程
- 尽量避免编码人员测试自己的程序
- 好的测试用例能够对未发现的错误高度敏感
- 成功的测试用例能够发现未知的错误
- 成功的测试需要仔细定义输入输出的期望值
- 成功的测试需要仔细研究分析测试结果
几个因素会影响到特定的测试和调试工作需要人工实际阅读代码的可能性:软件的规模和复杂度、软件开发团队的规模、软件开发的时限(例如时间安排表是松散还是紧密)等,当然还有编程小组的技术背景和文化。
代码检查、走查以及可用性测试是三种主要的人工测试方法。
“头脑风暴会”的目标是找出错误来,但不必找出改正错误的方法。换句话说,是测试,不是调试。
程序的错误总数始终是未知的。
代码检查可以发现错误,
其一,程序员通常会得到编码风格、算法选择及编码技术等方面的反馈信息
其二,其他参与者也可以通过接触其他程序员的错误和编码风格而同样受益匪浅。通常来说,这种类型的测试方法能够增强项目中团队的凝聚力,减少消极人际关系滋长的可能性,有利于打造高强度合作的、高效的以及信得过的开发模式。
用于代码检查的错误列表:
数据引用错误
数据声明错误
运算错误
比较错误
控制流程错误
接口错误
输入/输出错误
其他检查
代码走查
建议的参与者应该包括:
l 一位极富经验的程序员
l 一位程序设计语言专家
l 一位程序员新手(可以给出新颖、不带偏见的观点)
l 最终维护程序的人员
l 一位来自其他不同项目的人员
l 一位来自该软件编程小组的程序员
桌面检查
同行评审
对诸如下面的问题进行回答:
l 程序是否易于理解
l 高层次的设计是否可见且合理
l 高层次的设计是否可见且合理
l 修改此程序对评审者而言是否容易
l 评审者是否会以编写出该程序而骄傲
l 评审人还应给出总的评价和建议的改进意见
大多数的软件项目都应使用到以下的人工测试方法:
l 利用错误列表进行代码检查
l 小组代码走查
l 桌面检查
l 同行评审
l 另一种人工测试(基于人的测试)即使可用性测试,这是一种黑盒测试,需要测试人员站在最终用户实用的角度来评估软件的可用性程度。
测试用例的设计
最关键的问题是
在所有可能的测试用例中,哪个子集最有可能发现最多的错误?
就发现最多错误的可能性而言,随机选取而产生的测试用例集很少可能是理想的或接近理想的子集。
没有人曾承诺说:软件测试会是容易的事。引用一位智者的话:“如果你觉得设计和编写程序很困难,你就并非一无所知”。
白盒测试关注的是测试用例执行的程度或覆盖程序逻辑结构(源代码)的程度。
完全的白盒测试是将程序每条路径都执行到。
逻辑覆盖测试:这是合理的白盒测试中较弱的准则
判定覆盖或分支覆盖是较强一些的逻辑覆盖准则
判定覆盖通常可以满足语句覆盖
判定覆盖是一种比语句覆盖更强的准则
比判定覆盖更强的一些准则是条件覆盖
判定/条件覆盖准则
多重条件覆盖
满足多重条件覆盖准则的测试用例集吗,同样,满足判定覆盖准则、条件覆盖准则以及判定/条件覆盖准则。
黑盒测试
(数据驱动或者输入/输出驱动的测试)
等价划分
一个精心挑选的测试用例还应具备另外两个特性:
l 严格控制测试用例的增加,减少为达到“合理测试”的既定目标而必须设计的其他测试用例的数量。
l 它覆盖了大部分其他可能的测试用例。也就是说,它会告诉我们,使用或不使用这个特定的输入集合,那些错误会被发现,哪些会被遗漏掉。
这两种思想形成了称为等价划分的黑盒测试方法。
使用等价划分方法设计测试用例主要有两个步骤:
确定等价类
u 在给定了输入或外部条件之后,确定等价类大体上是一个启发式的过程。下面给出了一些指导原则:
u 如果输入条件规定了一个取值范围(例如,“数量可以是从1到999”),那么就应确定出一个有效等价类(1<数量<999),以及两个无效等价类(数量<1,数量>999)。
u 如果输入条件规定了取值的个数(例如,“汽车可登记一至六名车主”),那么就应确定出一个有效等价类和两个无效等价类(没有车主,或车主多于六个)。
u 如果输入条件规定了一个输入值的集合,而且有理由认为程序会对每个值进行不同处理(例如,“交通工具的类型必须是公共汽车、卡车、出租车、火车或摩托车”),那么就应为每个输入值确定一个有效等价类和一个无效等价类(例如,“拖车”)。
u 如果存在输入条件规定了“必须是”的情况,例如“标识符的第-个字符必须是字母”,那么就应确定一个有效等价类(首字符是字母)和一个无效等价类(首字符不是字母)。
u 如果有任何理由可以认为程序并未等同地处理等价类中的元素,那么应该将这个等价类再划分为小一些的等价类。稍后我们将给出这个过程的例子。
生成测试用例
第二步是使用等价类来生成测试用例,其过程如下:
- 为每个等价类设置一个不同的编号
- 编写新的测试用例,尽可能多的覆盖那些尚未被覆盖的有效等价类,直到所有的有效等价类都被测试用例所覆盖(包含进去)
- 编写新的用例,夫覆盖一个且仅一个尚未被涵盖的无效等价类,直到所有的无效等价类都被测试用例所覆盖
边界值分析
考虑了边界条件的测试用例与其他没有考虑边界条件的测试用例想比,具有更高的回报率。
好处于边界、或超过边界、或在边界以下的状态。边界值分析方法与等价划分方法存在两方面的不同:
1.与从等价类中挑选出任意一个元素作为代表不同,边界值分析需要选择一个或多个元素,以便等价类的每个边界都经过一次测试。
2.与仅仅关注输入条件(输入空间)不同,还需要考虑从结果空间(输出等价类)设计测试用例。
很难提供一份如何进行边界值分析的“详细说明”,因为这种方法需要一定程度的创造性,以及对问题采取一定程度的特殊处理办法(因此,就像测试的许多其他方面-样,这更多的是项智力工作,并非其他的什么)。然而,我们还是给读者提供一些通用指南:
1.如果输入条件规定了一个输入值范围,那么应针对范围的边界设计测试用例,针对刚刚越界的情况设计无效输入测试用例。举例来说,如果输入值的有效范围是—1.0至+1.0,那么应针对-1.0、1.0、一1.001和1.001的情况设计测试用例。
2.如果输入条件规定了输入值的数量,那么应针对最小数量输入值、最大数量输入值,以及比最小数量少一个、比最大数量多一个的情况设计测试用例。举例来说,如果某个输入文件可容纳1~255条记录,那么应根据0、1、255和256条记录的情况设计测试用例。
因果图
边界值和等价类划分的一个弱点是未对输入条件的组合进行分析
因果图有助于用一个系统的方法选择出一个高效的测试用例集。它还有一个额外的好处,就是可以指出规格说明的不完整性和不明确之处
生成测试用例时采用的过程如下:
1.将规格说明分解为可执行的片段。这是必须的步骤,因为因果图不善于处理较大的规格说明。举例来说,当测试一个电子商务系统时,“可执行的片段”可能是指对挑选和确认购物车中的单件商品的规格说明。在测试一个Web页面设计时,我们可能会测试一个单独的菜单树,甚至是一个不太复杂的导航序列。
2.确定规格说明中的因果关系。所谓“因”,是指一个明确的输入条件或输入条件的等价类。所谓“果”,是指一个输出条件或系统转换(输人对程序或系统状态的延续影响)。举例来说,如果某个事务引起文件或数据库记录被修改,那么这种改变就是一个系统转换,而系统反馈的确认信息就是一个输出条件。通过逐字逐句地阅读规格说明,同时标识出描述“因”和“果”的文字或句子,就可以将“因”和“果”确定出来。因果关系一旦确定下来,每个“因”和“果”都被赋予一个惟一的编号。
3.分析规格说明的语义内容,并将其转换为连接因果关系的布尔图。这就是所谓的因果图。
4.给图加上注解符号,说明由于语法或环境的限制而不能联系起来的“因”和“果”。
5.通过仔细地跟踪图中的状态变化情况,将因果图转换成一个有限项的判定表。表中的每一列代表一个测试用例。
6.将判定表中的列转换成测试用例。
评语:因果图方法是一个根据条件的组合而生成测试用例的系统性的方法。可以替代这种方法的是特殊选取的条件组合,但在这个过程中,很可能会遗漏很多可由因果图方法确定的“令人感兴趣的”的测试用例。
由于因果图方法需要将规格说明转换为一个布尔逻辑网络,因此它使我们从不同的视角,以更多的洞察力来审视规格说明。事实上,建立因果图是一个暴露规格说明中模糊和不完整之处的好方法。
错误猜测
由于无法给出一个规程来,次优的选择是讨论错误猜测的实质,最好的做法是举出实例。假设在测试一个排序程序,要探讨的情况如下:
·输入列表为空。
·输入列表仅包含一个条目。·输人列表所有条目的值都相同。·输入列表已经排过序。
测试策略
每一种方法都可以提供一组具体的有用的测试用例,但是都不能单独提供一个完整的测试用例集。一组合理的策略如下:
1.如果规格说明中包含输入条件组合的情况,应首先使用因果图分析方法。
2.在任何情况下都应使用边界值分析方法。应记住,这是对输入和输出边界进行的分析。边界值分析可以产生一系列补充的测试条件,但是,也正如“因果图分析”--节所述,多数甚至全部条件都可以被整合到因果图分析中。
3.应为输入和输出确定有效和无效等价类,在必要情况下对上面确认的测试用例进行补充。
4.使用错误猜测技术增加更多的测试用例。
5.针对上述测试用例集检查程序的逻辑结构。应使用判定覆盖、条件覆盖、判定/条件覆盖或多重条件覆盖准则(最后的一个最为完整)。如果覆盖准则未能被前四个步骤中确定的测试用例所满足,并且满足准则也并非不可能(由于程序的性质限制,某些条件的组合也许是不可能实现的),那么增加足够数量的测试用例,以使覆盖准则得到满足。
小结
攻击型的测试值得花精力尝试,一旦采纳,下一步的工作就是设计测试用例来充分检查你的程序。同时还应该考虑结合黑盒和白盒两种类型的测试以确保设计出来更精密的测试。
本章介绍了以下几种测试用例设计方法:
·逻辑覆盖测试。该测试要求程序中的所有判断都应至少覆盖一次,同时每一条语句或者入口点都被执行一次。
·等价类划分。通过定义条件和错误类来帮助减少测试的工作量。这种划分假设某分类的一个代表值能够等价于属于该分类的所有值或者条件。
·边界值分析。测试等价类中每一-个分类取边界值时的情况,既要考虑输入等价类,也要考虑输出等价类。
·因果图。通过生成布尔图来诠释测试用例的可能结果,使用该法旨在帮助选择那些有效地测试用例达到比较完整的测试用例设计效果。
##·错误猜测。依靠直觉和测试专家经验来定位程序可能出错的地方,并由此设计出更高效的测试用例。

浙公网安备 33010602011771号