《软件测试策略》——测试相关技术(识别bug)(一)

京东购买链接https://item.jd.com/10205955087769.html
到目前为止,本书主要讲述了测试设计和执行。这两方面固然重要,但忽略了一些重要内容,比如如何识别问题。当我们意识到存在问题时,就需要以一种经得起推敲的方式,向其他人传达这一问题的严重性。你可能会认为,发现错误并解释为什么需要修复,是一件简单甚至显而易见的事情......但如果真是如此,那为什么还有那么多软件存在非常多的 bug 呢?

为了提高效率,测试活动不仅需要发现对项目构成风险的问题,还需要以能促成改变的方式进行沟通。这些方式会因许多因素而有所不同,比如公司文化、接收信息的人、他们所承受的压力程度等,因此并不存在"唯一正确"的沟通方式。相反,沟通是一种技能,需要你在自己的工具箱里储备多种技巧,然后不断尝试行之有效的方法。本章的目标就是充实你的工具箱,并通过一些实例展示如何实施这些沟通技巧。

为了促成这一目标,本章将从以下方面进行介绍:

● 识别 bug---如何找到 bug ;

● 向利益相关者传达问题;

● 规划并记录工作;

● 衡量工作、进度和工作效果---度量指标;

● 推动变革。

6.1 技术要求

本章将探讨跟踪工作进度和收集工作信息的相关内容。至于如何具体实现,我们并不限定特定的方式。一个高效运作且高度互信的团队,可能只需在看板上贴上便利贴或用马克笔标记,并将测试中、测试完成的功能作为进度的主要衡量标准。然而在撰写本书时,采用了如Jira、Trello或Microsoft Teams等工具来跟踪工作进度,之后将数据导出到电子表格中进行度量统计,这种做法更为普遍。本书将为这两种极端情况及中间的大多数人群提供适用的解决方案。使用这些工具自行收集数据,将有助于你深入理解本章的要点,并且也可能为决策者提供关键信息。另一方面,如果缺乏这些工具,可能会让你感觉到工作中缺失了什么重要的元素。

几年前,Matthew 为一个团队培训时,该团队报告了一些 bug,但没有人关心。测试人员和开发人员在不同地点办公,因此 bug 被记录在一个没有人查看的数据库中。在这个软件系统中,用户可以在注册后通过输入无效的信用卡号获得访问权限。测试人员猜测,也许该服务正处于小范围试运营阶段,信用卡处理功能还未"接入"---这只是他们的推测。这个故事听起来可能有些不可思议,但类似问题在软件开发中却极为常见。

这个团队只做对了一半---他们发现了 bug。这是本章的起点。另一半是设定预期、沟通交流以及创建能激发行动的反馈,而这些正是他们所缺失的。

本章的目标是为你提供一套工具,避免陷入这样的困境。

6.2 识别 bug

从 20 世纪遗留下来的关于测试的普遍思维模式,或者说最响亮的观点,就是"制订计划并按照计划工作"。进行测试的人会依照一系列步骤操作,最后与"预期结果"对比。如果实际结果与预期不符,就提交一个 bug 报告。听起来很简单,对吧?

但实际情况"似乎"并非如此。实际情况是,测试人员遵循既定步骤操作,当发现这些步骤无法顺利进行时,他们就会报告 bug,等待新版本构建,然后再尝试从之前的某个环节重新开始测试。之前使用了"似乎"这个词,因为那已是过去式。如今许多客户在软件首次运行时,大体上都能取得较好的效果,关键在于"预期结果"。正如第 1 章中提到的,每一个带有预期结果的文档化测试用例都隐藏着一个第二断言---不会发生其他异常情况。如果你手头有一些这样的分步检查并对照预期结果的文档化测试,同时配合 bug 追踪系统,你可以比较一下,看看有多少 bug 来源于这些文档化测试用例。根据我们的经验,此类 bug 数量很少。

那么,bug 从哪里来?我们想问的是,它们是如何进入我们的认知范畴的?

通常是有人注意到了某些在他们看来不正常或不对劲的情况。

大多数人并不会刻意研究 bug 是如何被发现的。比如某个单词拼写错误,人们往往基于自己对正确拼写的认知模型来判断,他们会说:"我们知道它是错的"。但当我们深入探讨更复杂的用户界面问题,比如如何处理没有空格的换行、调整窗口大小,或是类似推荐书籍或电影的复杂算法结果时,确定什么是"错误的"就变得更为重要。在这种情况下,我们不再单纯依赖绝对的对与错,而是倾向于寻找一系列虽不完美但能帮助识别问题的方法。我们用"先知(oracle)"一词来描述这个过程。oracle 在此不是指数据库,而是更类似于古希腊的占卜者,他们能提供智慧。"先知"并非需求规范,也不一定完美无缺。例如,将这本书的内容粘贴到拼写检查器中,可能会因为包含像 DevSecOps 这类词汇而触发拼写检查警告,但实际上这些词汇是正确的。即便如此,拼写检查仍然是一个帮助发现问题的有效途径。

6.2.1 软件测试中的"先知"

需求:绝大多数关于测试的文献都将重点放在了需求上,这是一个压倒性的默认假设。这些需求可能是团队成员共同的思维模型,以文档形式记录下来,甚至可以作为自动化的实例需求。但经常被忽视的一个寻找测试思路的地方就是这些文档本身。文档中常常包含分开列举的功能特性表,但如果我们同时使用这些特性会怎样呢?例如,1993 年款的福特 Escort 允许 Matthew 同时打开暖气和空调,但这对两个系统来说都不是好事。

字典、标准或共识:大多数人都知道 1 英尺等于 12 英寸。同样地,看到屏幕上显示的某个内容时,我们也能够直观地感觉到哪里不对劲。例如,当你保存一个含有特殊西班牙语字符(如"café")的单词,但结果却显示成一个带点的方框,你会立刻意识到有问题。这就是国际化处理失败的一个例子,就像在第 5章讨论的那样。在软件测试中,最普遍被接受的标准可能是同类产品的标准,接下来我们会详细讨论这一点。

同类产品:现代办公应用程序通常有一个熟悉的菜单栏,其中 (F)ile 选项通常位于最前面(图 6-1)。在 (F)ile 下拉菜单中,按照以下顺序排列有 (N)ew、(O)pen、(S)ave、(P)rint 和 (E)xit 之类的选项。

图 6-1 经典文件菜单

我们期望这样的行为模式,只是因为几乎所有的应用程序都是这样的。这种现象被称为"同类产品参照法则"---即当软件的行为与其他软件不一致时,我们就会觉得哪里出了问题。例如,视频播放应用应该在点击时开始播放,再次点击时暂停,且空格键也应该具有相同效果。如果软件的行为与同类产品不一致,其可能是有意为之---某种创新设计。但这种情况下,我们期望需求文档能够说明这一差异并非疏忽或错误。

注意: 甚至 Mac 系统上的软件也遵循 Microsoft 用户界面标准。

眨眼测试(Blink Testing):这一概念源自马尔科姆 · 格拉德威尔(MalcolmGladwell)的著作《眨眼之间:不假思索的决断力》,书中提供了人类在有限信息下产生洞察力的例子。迈克尔 · 博尔顿(Michael Bolton)将这一概念进一步形式化为一种"先知"(oracle)。进行眨眼测试时,你可以通过迅速浏览日志文件或随机文本输出,快速判断测试,例如有无特殊字符(或特殊字符过多、数字过多等情况)。眨眼测试通过快速放大和缩小视角来完成,即在短时间内快速捕捉并分析信息,依靠直觉和经验识别潜在问题。

另一个程序:在模型驱动测试中,我们可能会编写一段代码来执行与被测软件相同的数据转换操作,将相同的输入分别输入这两个程序,然后比较两者的输出结果,以此来判断是否存在差异,即问题是否出现。

历史比较法:或许最简单的"先知"就是比较软件上个版本与当前版本的运行情况。如果两者之间存在差异,并且这种差异不能从预期的变更中直接推断出来,那么这个变化很可能不是有意为之,即意外的副作用或错误。

在我们的工作经历中,遇到的最具挑战性的测试问题,是在没有明确定义软件应当如何表现的情况下出现的。在这种情况下,可执行测试能为我们提供帮助,因为在某一时刻,我们希望某个具有权威性的人定义在这些复杂的转换条件下,给定这一组输入应当产生特定的输出结果。正如我们的评审员弗里 · 纳德曼(JeffreyNadelman)所建议的,我们应该称此为"运行可执行程序来自动检查标准"。

有时,我们的"先知"也会失误或失败,这可能是因为我们在错误的地方寻找问题。

6.2.2 非注意盲视与"先知"

让我们通过一个练习来探讨如何发现问题。在开始之前,如果条件允许,请先上网观看一个关于非注意盲视(Inattentional blindness)的视频。在编写这部分内容的时候,YouTube 上有一段名为"非注意盲视-传球计数"(InattentionalBlindness--How Many Passes)的视频。在视频中,有两支队伍,一支穿着白色衣服,另一支穿着黑色衣服。挑战为:计算白衣队伍在大约 12 秒内的传球次数。笔者在此插入一张图片(图 6-2),这张图片没有特定意义,目的仅仅是打断你的阅读,给你时间去观看视频。

图 6-2 添加图片以防止剧透(图片由 Matthew 的女儿 Juliana Heusser 提供)

无论你是否去看了该视频,现在是时候讨论它了。

在 12 秒视频中,表面目标是计数白衣队伍传球的次数,这与遵循"测试脚本"执行测试颇为相似。然而,视频中有个令人惊讶的部分:你是否看到了一个穿着熊装的人,跳着舞横穿画面?我们在几大洲与数千人进行过这个练习,但至今未曾有人当即表示:"哦,是的,我看到了那只熊。"

在软件测试中,那只熊象征着一个 bug,或者至少暗示着某些值得深入探究的线索。这是一个没有被发现的 bug,因为我们过于专注于遵循一套特定的指令。这说明了详尽文档化的测试步骤可能限制了我们从整体系统角度审视软件的能力。测试人员往往会产生狭隘视野,只检查预期结果,而忽视了其他可能的异常。因此,关注如何发现 bug 的途径就变得尤为重要,同时认识到"点击-检查"式自动化测试风格的局限性也同样关键。上述的熊不仅仅是一种类比,更是直接映射了软件自动化执行的过程。步骤对比测试工具永远不会说"这很奇怪""嗯"或"这看起来不对"这样的主观判断。第 2 章末尾提出了一些减少此类风险的思路,融合了人工与机器的优势,比如采用视觉测试技术。

对于非注意盲视现象,有几种应对方法。一种是多次从不同角度审查同一软件。在第一轮中,你可以模拟用户的使用旅程;在第二轮中则可以创造一些异常或无效的条件来触发错误。同样,一轮审查可以遵循脚本化的、定义好的步骤(或者让计算机借助工具来执行这些步骤),而另一轮则更加注重探索性。另外,你还可以进行混合测试(mixup testing)---这是一种 Scrum 团队之间的跨团队测试活动,曾在 2012 年的 Øredev 大会上作为一个议题进行讨论,团队成员测试他们并未参与开发、不熟悉的软件,以初学者的心态进行测试。

通过测试,我们可以运行软件并发现 bug,但除非我们注意到问题并采取行动,否则它们不会得到解决。研究"先知"问题能帮助我们识别什么时候存在bug,即那些对重要人士构成困扰的问题。在深入讨论 bug 报告之前,先花点时间谈谈我们是如何定义 bug 的。

6.2.3 关于 bug 一词

在本书中,我们特意使用"bug"这一单词,它是软件中真正困扰用户且值得讨论的问题。这类问题可能是一个不值得修复的小毛病,可能修复起来非常简单;也可能阻碍工作,比如严重的登录错误,但存在一个显而易见的解决方法;还可能表现为功能的缺失。与之相比,"缺陷 (defect)"这一单词则意味着某种错误,即不符合规格说明书(或需求)。根据我们的经验,使用"缺陷"一词意味着程序员可能犯了一个错误。这往往会引发关于什么是缺陷、什么不是缺陷的争论。而在这些讨论中,我们并没有发现太多价值。相反,现在我们更关注的是问题是否需要修复或以任何形式记录下来。

下一节,我们将讨论 bug 报告。