写点什么

使用 TextTest 来做认定测试

  • 2017-03-05
  • 本文字数:3261 字

    阅读完需:约 11 分钟

认定测试(Approval Testing)是一种测试技术,它比对代码的当前输出和“已认可”的版本。最初检查测试输出时,若对认可结果即则会形成这个所谓“已认可”的版本。当需求变更时,你可以重新审视这个已认可的版本并轻易更新它。TextTest 已支持认定测试,这是一款开源工具,用于基于文本的功能性测试。

Emily Bache 是一名培训师、软件开发人员和架构师,在欧洲测试大会2017 上召开了一个研讨会,主题为使用TextTest 进行认定测试。InfoQ 通过问答、总结和文章的方式全程报道了此次会议。

Bache 首先解释了基于认可的测试的概念,以此作为研讨会的开场白。她展示了如何在 TextTest 中建立测试,然后首次运行它去产生输出数据。

该研讨会的参会者实践了使用 TextTest 进行基于认可的测试,定义了新的测试用例并运行了它们。在首次运行一个测试时,如果认为程序运转正确,则会生成一个输出,再次运行时会检查这个输出,如果输出没问题,那么它们就会对它进行审核,把测试标记为“通过”。

如果输出有问题,那么他们就发现了缺陷。那么这个输出就不是被认可的,测试人员可以把它指出来或在这个输出里为开发人员加条备注,待修复之后再审核它,Bache 说。因为本次产生的输出与之前已认可的输出不同,所以 TextTest 将把该测试标记为“失败”。如果程序更新了,缺陷消除了,那么这个测试会被再次运行,并将通过。

InfoQ 有幸就认定测试技术采访了 Emily Bache,并请她谈了谈如何使用 TextTest 来做认定测试。

InfoQ:什么是认定测试?

Emily Bache: 其基本理念是,通过比较代码的当前输出与之前运行的测试所形成的“已认可”的版本,来决定测试是否通过。

所以你首次运行一个新的测试时,没有任何可用来比对的已认可版本。你也许大致知道预期的结果,也许你脑中有个大概,或者用户故事交流中的一些笔记让你记得应出现什么情况。你手工检查代码的输出,决定它是不是足够好了。如果你不确定,可以做些计算,或者把它展示给专家级的用户。一旦你做出决定,认为该行为值得保留下来,将“认可”该输出并把它保存起来。然后所有后续测试将比对实际结果与这个已认可的版本。通常,你可以使用简单的文本比较工具来做这种比对,任何差异都认为这个测试是失败的。

如果你看过一些像“扫地雷(Minesweeper)”这样的编码套路,问题在于 ascii 码形式的输入(地雷的范围区域)和预期输出(同一范围区域,但还有地雷和邻近的地雷数)。使用基于认定的测试就能很好地完成这个工作,因为每个测试用例比较一个输出雷区和已认可的输出方案。当测试失败时,差异通常能清楚地展示出什么出错了。其实,我们已经把它做进了一个认定测试小练习中了,并把它公开发布到了 github 上: Minesweeper Approval Kata

你可以设计一些新的雷区(也许是真正偏僻的问题?)并把它们放入认定测试中。我已经完成了一些与 Yatzy 和 Gilded Rose 套路很类似的事,以展示即使输出不是图形化的,此方法同样有效。

InfoQ:认定测试与基于断言的测试有怎样的不同?

Bache: 在“基于断言”的测试中,你必须选择输出的一个方面进行检查,然后写特定的代码去检查它。我们经常讨论这种测试所具有三个部分:准备、执行、断言。在认定测试中,前两部分是一样的,而第三部分有所不同。测试设计人员仍决定要测试什么场景,以及如何去触发该场景,但不预先定义将输出什么,至少不含任何细节。一旦你有了测试的前两部分,就可以开始执行并评估输出了。如果输出不够完备或比较粗略,你可以继续维护产品代码,直至输出值得保留为止。当你对它足够满意时就可以“认可”这个结果并把测试分享给团队,而没必要等到故事末期。这种测试具有天然的“敏捷性”,当需求变更时,你可以重新审视这个已认可的版本并轻易更新它。

InfoQ:你在认定测试中是如何使用 TextTest 的?

Bache: TextTest 是一个开源工具,我和其他一些人现在已经使用它很多年了。它初衷设计为语言无关的,它的测试处于可执行程序层,而不是单独的函数或类上。例如,我已经用它测试过用Java、Scala、C++、Python 和 Ruby 的程序了。

不仅可以测试整个程序,TextTest 还会完成纯文本输出的比对。当然,并非所有程序的正常功能的输出都是纯文本的,但大多数输出物都可以转换为纯文本。例如,PDF 或 HTML 文件就能转换为纯文本,复杂的用户界面可以描绘成 ascii 形式,数据库可以查询输出为纯文本报表。以我的经验来看,为你的应用创建一个做此类转换的测试工具是值得的,它将在许多测试用例中得到复用。如果你的测试主要由纯文本内容的文件目录结构构成,就有很多可以自由使用的工具了,搜索、比对、正则表达式和版本控制等等。

InfoQ:什么时候做认定测试,又有哪些收益呢?

Bache:我通常把认定测试用于端对端的测试或 API 测试,在这种情况下你想要确认的是整个特性按用户预期工作。我认为它很自然地遵循了“认可”输出的需要,你希望测试所围绕的基础是用户或领域专家能够阅读和理解的东西。如果你能在他们熟悉的工具(比如 PDF 文档、网页或用户界面截图)中为他们展示测试结果,那么他们可能更相信测试正在检查的是他们关注的东西。基于断言的测试通常对于他们来说太难理解了。

基于断言还有个弊端是针对每个新测试用例都要写新的断言代码。如果你使用认定测试,则可以经常复用为之前的测试用例所写的测试工具。我认为总体上维护的代码要更少一些。

我经常在遗留代码上使用这种方式,这些是仍会被使用的代码,但缺少测试覆盖,难以保证在不被破坏的情况下对其进行变更。仅仅触发不同的场景并认定这些程序的所有输出都是正确的,你就能快速获得一套适当的回归测试了。

这些都是好的方面,但认定测试的“杀手级特性”是能够找到设计测试时未预期到的缺陷。若使用基于断言的测试,你就得明确判定输出有哪些方面要予以检查。你断言,这个左上角的正方形紧邻着两颗地雷。这张发票显示应付数额、银行存款数额和客户编号。但是,如果雷区漏掉最后一列会怎么样呢?或者账单包括的是账单跟踪信息而不是投递地址呢?你会记得去为它们写断言吗?

默认情况下,认定测试将比对整个输出,以我的经验来看,这是个发现这类问题的好机会。实际上,输出中有的内容是你不想检查的,这种情况经常发生。你可能显示了今天的日期、流程编号或随机数,这些东西随时都会变,在与已认可的版本进行比对前需要先过滤掉它们。但是,测试设计人员的角色发生了转变,不再是选择哪些东西要断言,而是选择哪些东西要忽略。总而言之,你有更多的可能发现这些意料之外的变化,免得被它们弄得顾此失彼。

InfoQ:如果测试人员想要了解认定测试的更多内容,可以去哪里呢?

Bache:好的,首先我不认为这是一项仅针适用于测试人员的技术。我认为所有开发人员在对他们代码进行测试时都能得到收益,在开发新功能的时候,你可以运用此技术以测试驱动的方式开展工作。我的经验表明,如果开发人员、测试人员和专家级用户或产品负责人能在一起做这个测试套件,会从中得到更多的收益。

我认为学习一项新技术的绝佳方式是在你已经熟悉的问题上进行尝试。如果你之前曾研究过扫地雷、骰子游戏或镀金玫瑰编程套路,建议你在我的 github 页面上看一下它们的认定测试版本: Yatzy Approval Kata GildedRose Approval Kata 。只要你去了,就能用我的每个“示例解决方案”来比对你的测试了。我计划增加更多的练习,如果你有特别喜欢的编程套路想要看到以此方式解决的话,请写信给我。

如果你喜欢了解这个方法的背景、具体经验和理论依据的话,有许多相关的文章甚至科学论文。例如,在我的书《 Mocks, Fakes and Stubs 》(尚未完成)中就有一篇写了认定测试,其中包括一些免费示例可供下载。一名学者做的项目研究也被我收录了进来,而且研究成果也发表在了《 the industrial applicability of TextTest 》论文中。在我的博客上有一篇关于认定测试的文章,里面讲述了其他人如何使用此类方法进行测试。Llewellyn Falco 特别为此主题整理了许多资料,包括截屏和视频,请点击在.Net 中使用认定测试查看。你还可以在 texttest 网站上找到一些文章和用户文档。

查看英文原文 Approval Testing with TextTest

2017-03-05 18:001857

评论

发布
暂无评论
发现更多内容

深度理解NodeJS事件循环

coder2028

node.js

时间旅行调试与自动化测试的支持

iofod jude

前端 低代码

一文读懂Js中的this指向

hellocoder2029

JavaScript

实验精神终将胜利:量子纠缠的祛魅七十年

脑极体

阳振坤:分布式技术引领关系数据库发展

OceanBase 数据库

DataOps核心理念是什么?包括哪些模块?

雨果

DataOps

Red Hat Releases OptaPlanner 8

积木思维

理解NodeJS多进程

coder2028

node.js

详解CAN总线:CAN总线报文格式—过载帧

不脱发的程序猿

汽车电子 CAN总线报文格式 详解CAN总线 CAN过载帧

webpack热更新原理(面试大概率会问)

Geek_02d948

webpack

星汉未来 | 云原生薪火计划——开源大使招募

星汉未来

开源 开发者 云原生 星汉未来 FinOps

被翻译成 12 种语言的深度学习名著重磅升级,75%新内容,让你豁然开朗!

图灵社区

Python 深度学习

详解CAN总线:CAN总线报文格式—遥控帧

不脱发的程序猿

汽车电子 CAN总线报文格式 详解CAN总线 CAN遥控帧

我为什么要使用 Tauri 构建 macOS 磁盘清理工具 PrettyClean

NinetyH

tauri ​Rust

被翻译成 12 种语言的深度学习名著重磅升级,75%新内容,让你豁然开朗!

图灵教育

Python 深度学习

js作用域、作用域链和它的一些优化

hellocoder2029

JavaScript

令人头疼的Javascript隐式&强制转换

hellocoder2029

JavaScript

【愚公系列】2022年10月 Go教学课程 024-函数

愚公搬代码

10月月更

数据治理,七种常犯的错误

雨果

数据治理

从手动测试到自动化测试(上)

FunTester

webpack模块化的原理

Geek_02d948

webpack

为什么最近关注“元数据”的人突然增多?

雨果

元数据 元数据管理 元数据管理平台

数字化转型最核心的是数据吗?不,是数据思维

雨果

数字化转型 数据思维

详解CAN总线:CAN总线报文格式—错误帧

不脱发的程序猿

汽车电子 CAN总线报文格式 详解CAN总线 CAN错误帧

详解CAN总线:CAN总线报文格式—帧间隔

不脱发的程序猿

汽车电子 CAN总线报文格式 详解CAN总线 CAN帧间隔

小程序容器技术,或许是提升智能设备安全等级的又一解决方案

Speedoooo

浏览器安全 小程序容器

Vue组件入门(一)组件定义及使用

Augus

Vue3 10月月更

后端Java随机比大小游戏实战讲解

魏铁锤

10月月更

一文了解 Python 中的对象比较方法 is 和 ==及其本质

宇宙之一粟

Python 10月月更

爬虫练习题(五)

张立梵

Python. 10月月更 爬虫案例

说说Nodejs高并发的原理

coder2028

node.js

使用TextTest来做认定测试_软件工程_Ben Linders_InfoQ精选文章