我最近偶然发现了这种新的(至少对我来说)测试类型:快照测试:


对于Facebook的本机应用程序,我们使用称为“快照测试”的系统:快照测试系统呈现UI组件,截取屏幕截图,然后将记录的屏幕截图与工程师所做的更改进行比较。如果屏幕截图不匹配,则有两种可能性:要么更改是意外的,要么可以将屏幕截图更新为新版本的UI组件。


有人尝试过吗?这种测试什么时候适用?这是对单元测试的替代还是只是编写它们的一种方式/方式?它仅适用于UI测试吗?

评论

也许是与发布版本相比对工件快照版本的测试?查看您的链接,我会说我错了。但是链接往往会中断,因此也许最好在此处引用部分链接内容?

@dzieciou好主意,用更通用的名称替换了链接,并添加了引号。谢谢。

#1 楼

正如彼得·马西亚(Peter Masiar)所指出的,您基本上可以将其与“黄金标准”进行比较。因此,我想说这是表征测试/黄金大师测试的衍生产品:保护它免受意外更改,无论其正确性如何。为此,以前的(通常是稳定的)版本的结果(即“黄金母版”)用作测试的Oracle(也称为一致性Oracle,因为它比较两个版本之间的一致性)。


特性测试(由Michael Feathers在他的书“有效地使用旧版代码”中创造)具有多种不同的风格: )
批准测试(由TextTest使用)
视觉测试(由Applitools使用)
感知差异测试(由Depiced使用)


有些像素比较,其他人则进行文本比较,还有混合方法(roesslerj提到)。每个变体都有其优点和缺点,但本质上是相同的心态:与先前版本进行比较,无论其正确性如何。还有一个非常酷的介绍(“小马舞曲”从4:26开始),由Google开发了描述的基本概念。

回到Jest,您在问题中的报价可能有点误导,因为在笑话中,“快照”并不表示“屏幕截图”,即没有像素比较。考虑以下来自他们文档的示例: “(.snap后缀):

import React from 'react';
import Link from '../Link.react';
import renderer from 'react-test-renderer';

it('renders correctly', () => {
  const tree = renderer.create(
    <Link page="http://www.facebook.com">Facebook</Link>
  ).toJSON();
  expect(tree).toMatchSnapshot();
});


这是您的黄金大师,其中包含渲染的React组件的文本表示形式: br />在随后的测试运行中,Jest将简单地将渲染的输出与先前的快照进行比较。如果它们匹配,则测试将通过。如果它们不匹配,则测试运行器在您的代码中发现了应修复的错误,或者实现已更改,并且快照需要更新。


如果经过测试对树进行更改(例如更改到其他链接),您将获得一个简单的文本差异:



据Jest团队介绍,与像素比较相比,它具有以下优点:




没有脆弱性:因为测试是在命令行运行程序而不是真实的浏览器或真实的电话上运行的,所以测试运行程序不会必须等待构建,生成浏览器,加载页面并驱动UI才能使组件进入预期的状态,该状态往往会变得不稳定并且测试结果变得嘈杂。在不到一秒钟的时间内获得结果,而不是等待几分钟甚至几小时。如果测试不能像大多数端到端框架中那样快速运行,则工程师根本不运行它们,或者根本不用费心编写它们。

调试:很容易进入JS中的集成测试代码,而不是尝试重新创建屏幕快照测试方案并调试视觉差异中发生的事情。




最后一点,Jest不是React独有的。它具有序列化程序的概念,该序列化程序负责读取/写入快照文件。对于内置的JavaScript类型,HTML元素,ImmutableJS和React,有默认的序列化程序,但是您也可以编写自己的序列化程序。

因此,从理论上讲,您可以编写单元,集成和系统测试与开玩笑。我只是认为这总是没有道理的。例如,当您有一个简单的add函数将两个整数相加时,为什么要对结果使用快照文件?一个简单的旧断言就可以了。

评论


优秀,推荐。以我的经验,尝试通过使用不同的工具(不是真正的浏览器)绕过脆弱性可能会导致不同的脆弱性:由该工具和真实浏览器之间DOM处理的实现方面的细微差异引起。这是“挑毒”游戏,没有真正好的答案,也没有银弹,AFAIK。我建议“减少fl断感”。 “没有脆弱性”是蛇油推销员的承诺,而不是您自己的话-可能您只是从营销页面上复制粘贴了。 :-) Jest是开源的吗?

–Peter M.-代表莫妮卡(Monica)
17/09/21在15:00



@PeterMasiar完全同意。每当我读到“没有脆弱性”时,我都会以为“ naaah”。但是我自己为工具供应商工作,所以我要说些什么... ;-)

–beatngu13
17年9月21日15:12

在这里,我们不仅需要来自战es中的家伙(像我一样)的洞察力,还需要来自那些可以说“正在制造我们的武器”的家伙的洞察力-很高兴您能来这里!

–Peter M.-代表莫妮卡(Monica)
17年9月21日在16:28

另请参阅sqa.stackexchange.com/questions/29735/中@ beatngu13关于Galen的评论-

–Peter M.-代表莫妮卡(Monica)
17-09-21在18:40



#2 楼

这种测试仅测试网页的外观,因此绝不是单元测试(测试模块的内部逻辑)的有效替代。但这可能是集成/系统测试的一部分。

Applitools.com称其为“可视测试”并为其提供了框架。他们的框架允许忽略屏幕图像的某些部分(例如显示日期/时间的部分),将其余像素逐像素进行比较,并突出显示“黄金标准”之间的差异(如果有)。只需单击一下,您就可以将新屏幕接受为新的“黄金标准”。

此类视觉测试不能替换基于Webdriver的标准集成/ e2e测试,因为它仅限于图像。因此,例如,无法执行硒可以执行的活动,例如:从页面上的列表中随机选择一个“东西”,转到另一个页面,并根据业务逻辑的要求检查thingie是否存在(或不存在)。为此,这将需要强大的OCR和更多的编程(这将浪费时间,因为selenium / webdriver已经可以做到,而且容易得多)。

但是这种可视化测试非常出色对selenium / webdriver测试的补充,因为它可以精确检查selenium忽略的页面内容。因此,在对库进行单元测试,对单页应用程序进行单元测试(角度/量角器)和e2e硒测试(按优先级顺序)之后,它是出色的附加防御层。不适用于applitools且不使用其工具,但是我看了一个演示并且该技术看起来很酷-将来有时会在我的列表中尝试。

评论


很好的答案,但请注意,在Jest的情况下,“快照”并不表示“屏幕快照”,即没有像素比较。请参阅他们的常见问题解答:“使用Snapshot测试值会序列化,存储在文本文件中并使用diff算法进行比较。”

–beatngu13
17年9月20日在21:32

@ beatngu13-我不确定Applitools的工作方式(从简短的介绍开始,它看起来像图像处理),而且我不确定如果不是图像处理(像素到像素比较),diff将如何有用。什么是“笑话快照”?希望写出解释差异的答案,并附上链接(如果有)?

–Peter M.-代表莫妮卡(Monica)
17年9月20日在21:39

这是我的答案,希望能对您有所帮助。

–beatngu13
17年9月21日在8:01

@ beatngu13-非常好,推荐。

–Peter M.-代表莫妮卡(Monica)
17年9月21日在14:53

#3 楼

还有一种混合方法,可以通过诸如ApprovalTests,TextTest和ReTest之类的工具来实现。一般的想法不是检查单个元素,而是一次检查所有内容。如果内容没有更改,则布局也不应更改。

像素比较工具的问题在于批量更改。如果您更改徽标,则每项测试都会失败,必须手动进行审查/批准。

披露:我为ReTest工作。