最后一章,我将关于实践中测试内容的建议和要点整理成精简的格式。这些信息在本书的各个章节中都零星出现过,只不过,那时它们都出现在各自的上下文中,关注的焦点也可能在别的地方。本章中,它们将是重点。我希望这些材料能帮助你对测试进行选择并制定优先级,因为真实的项目中总是会面临进度压力,而且在实践中"穷尽测试"也是不可能的。
19.1 高层注意事项
在编写测试用例时,团队以及每一个开发人员都需要对测试的重点做出很多决定。本章将就"从哪里开始测试""测试什么"的话题提供一些论据,以及给出测试设计的一些思路。
19.1.1 测试有效性
根据系统状态的不同,某一种类型的测试可能比其他类型更有效。
· 单元测试。是否进行测试驱动开发的实践,是专业化的新代码开发时必须考虑的问题,也就是说,是否为了将来的可维护性,在现在与其他人一起花一些代价进行这样的实践。测试用例的存在能确保代码具备可测试性,而且它们也可以作为规格的一种形式。
· 组件/服务测试。这种测试会覆盖许多功能,其中也包括持久化机制的正确性,只要该机制是由系统内职责明确的可分隔组件实现的。
· 端到端或系统测试(也可能是集成测试)。当老系统的代码过于复杂导致单元测试无法开展或太过耗时,或者复杂到无法区分出任何组件时,这类测试可能更有效,因为,它们能够提供对关键功能的覆盖,并能更快地实现回归测试。
19.1.2 测试配方
测试配方 帮你选出测试内容,这在进行单元测试时特别有帮助(因为单元测试包含了总量最多的细节信息)。本节的三个测试配方采用不同的措辞,可能其中某一个特别符合你的喜好,如果是这样的话,我鼓励你追溯一下原始来源,对配方中的问题给出准确、详尽的描述。
配方#1(Vance 2013)
· 测试主逻辑路径(happy path)
· 测试备选路径,即正常行为的有用变化
· 测试错误路径
· 测试数据变换
- 边界条件
- 数据驱动执行
- 运行时绑定和动态绑定
· 测试缺陷(缺陷回归测试)
配方#2(Langr, Hunt, &Thomas 2015)
Right BICEP(助记方式)如下。
· Right:结果是否正确
· B:Boundary,边界条件
· I:Inverse,反向关系(用于实现逆向测试)
· C:Cross-check,使用其他可信来源进行交叉核对
· E:Error,错误条件
· P:Performance,性能特征
配方#3(Beck 2002)
对于你已经写完的代码,测试:
· 条件语句
· 循环
· 操作
· 多态性
19.1.3 抽象级别及其细节
考虑一下你的下一个测试在哪个抽象级别上开展,它需要关注的细节有多少,测试使用什么语言·
单元测试(可能还有集成测试)。单元测试应该覆盖全部底层结构,例如输入的不同变换、边界值、数据驱动测试、输入校验,以及穷尽的分支覆盖。这种测试可能会在测试代码中使用技术术语,但是仍会尝试去测试那些从用户角度看有意义的操作。
系统或端到端测试。系统和端到端测试应该执行更为重要的部分,并确认系统作为一个整体在运行。这种测试不应忙于验证细节和变化,而应该跨越场景和用例,并且使用业务的语言。
19.1.4 原型
测试符合哪种形式,它覆盖了多少种情况·
· 单个例子。测试执行的是一些特定的行为,预期得到特定的正确答案。
- 变体:场景--测试模仿一个用户与系统的交互过程。
· 表格/数据驱动。测试中用许多不同的值和预期结果来执行同一个逻辑。
- 变体:理论--测试中使用预选输入值的不同组合,验证结果是否满足某种概括性的声明。
- 变体:状态转移--这是若干种测试方法中的一种,用来验证系统中适宜用状态机建模的那部分特性。
· 生成。测试生成了测试代码的参数,可能生成了许多次。
19.1.5 可信来源(结果判断依据)
如何才能知道结果是正确的·
· 单一值。某个单一值是唯一正确的答案。
· 范围。正确值落在一个已知范围或区间内。
· 集合。有多个正确值,它们相当于一个有限大小的集合。
· 判定。结果值是否正确,是由一个输出结果为"是"或"否"的函数来判定的。
· 交叉核对。可以用一个替代实现(用另一种方式实现)来断定结果值是否正确。
· 逆函数。将测试代码产生的结果用作逆函数的输入,处理结果会与测试的输入一致。
19.2 低层注意事项
本节包含你在对一些常见程序元素进行测试时,需要考虑的事情。这个列表并不完备,但是如果你记住了这些点,你的测试将会覆盖大部分的情况。
19.2.1 0-1-n
确保测试覆盖以下内容:
· 0个实例。空集合/队列;从未进入执行的循环/条件块;可能的空值(null)等。
· 1个实例。有一个元素的集合/队列;返回一个元组的查询;执行了一次的循环等。
· 多个实例。有多个元素的集合/队列;返回几个元组的查询;执行了若干次的循环等。
19.2.2 空值(null)
只要类型/队列/集合允许,尽可能用空值(null/nil/undef)来试探一下,看看会发生什么。
19.2.3 范围
对于范围m~n,检查如下输入时的行为:
· m · 1
· m
· n
· n + 1
19.2.4 集合
应考虑以下内容:
· 空
· 有一个元素
· 有多个元素
· 包含重复元素
· 调换元素顺序
19.2.5 异常和错误
考虑以下几点:
· 异常类型(类)
· 异常消息
· 嵌套异常
· 其他异常参数
· 检查所有错误代码(在你已经完成的代码中)
19.2.6 数字
记住以下几点:
· 零
· 负数
· 超出基本数据类型范围
· 浮点数的精度
· 其他表示方法(如十六进制、八进制、科学计数法)
· 数字以需解析的字符串表达时,需要测试逗号、句号(英语的句号)、空格
19.2.7 字符串
不要对以下内容感到惊奇:
· 空字符串(空白)
· 一个空格
· 几个空格
· 特殊字符,例如\n、\r、\t等
· 以空白或特殊字符开头或结尾
· HTML实体
· 非ASCII字符
· 编码
· 固定大小字符串缓冲区溢出
19.2.8 日期
注意以下几点:
· 不同格式
· 每个月的天数
· 闰年
· 时区
· 夏时制
· 精度(日期是否包含时间部分·)
· 时间戳格式
19.3 小结
当思考接下来开展什么测试,以及如何开展的时候,请考虑以下内容:
· 哪种测试类型最有效·
· 是否有一个配方来指导如何选择接下来的测试内容·它的建议是什么·
· 测试在哪个抽象级别上开展·
· 它是什么风格(原型)的·
· 它将使用哪个可信来源(来判断结果是否正确)·
在创建测试用例的时候,所有常见数据类型和抽象都有其特定的问题需要解决。
版权声明:51Testing软件测试网获人民邮电出版社和作者授权连载本书部分章节。
任何个人或单位未获得明确的书面许可,不得对本文内容复制、转载或进行镜像,否则将追究法律责任。