俄罗斯贵宾会-俄罗斯贵宾会官网
做最好的网站

测试你的前端代码:可视化测试

测试你的前端代码:可视化测试

2017/10/25 · CSS · 1 评论 · 测试

原文出处: Gil Tayar   译文出处:oschina   

测试 App,你从哪里开始?在最后这个部分,第五部分,Gil Tayar 总结了他为前端测试新人写的系列文章。最后这篇文章中,Tayar 讲述了可视化测试,以及为什么它是测试前端代码的最后一步。

不久前,我一个刚刚进入精彩前端世界的朋友打电话问我该怎么测试他的应用程序。我告诉她有太多需要学习的东西,在电话里根本说不清楚。我答应发送一些对她前端之路有所帮助的链接。

所以我在电脑前坐下,通过 Google 搜索相关的主题。我找到很多链接,也发送给她了,但我对这些链接讨论的深度并不满意。我找不到一个全面的指南 —— 以新入行的前端的角度 —— 指导如何测试前端应用。我没找到某个指南既讲理论又讲实践,同时还是面向前端应用的讨论。

因此,我决定写一个。这已经是这一系列的第五部分了。你可以在下面看到其它部分:

另外,为了写这篇文章,我写了一个小应用 —— Calculator(计算器) —— 我要用它演示测试的不同类型。你可以在这里看到它的源代码。

可视化测试

软件测试一直是我的一大爱好。最近,我觉得没有测试就写不出代码。对我来说,有一种原始的想法,运行的目的就是为了验证代码是否正确。你的意思是告诉我,在以前,每次开发者修改他们的代码,都需要有人手工去验证之前正常的事情仍然正常?是这样吗?

因此,我写测试。因为我喜欢演讲和写博客,我会演讲或写关于软件测试的内容。如果有机会进入一个对加强软件测试有着卓越远见的公司,写代码来帮助其它人写测试,并推广他们的产品,我会毫不犹豫的加入。

正是如此,我最近加入了 Applitools (如果你想知道职位,是布道师和高级架构师)。因为他们的产品,Applitools Eyes,与我写的这个系列有着直接联系,我决定在这个系列中多写一个部分 —— 一个关于“可视化测试”的部分。

还记得我的疑惑吗?开发者实际总是会在每次修改他们的代码之后运行他们的应用。嗯,到目前为止,软件产品需要手工测试 —— 这是在应用的可视化方面。还没有办法检查应用看起来仍然是好的 —— 字体是正确的,对齐没有问题,颜色也还在,等等。

理论上你是可以写代码来进行相关的检查。我们在第三部分了解到如何使用 Selenium Webdriver 测试 Web 应用的 UI。我们可以使用 Selenium 的 getScreenShot API 来获得页面的截图,将其保存为基准,之后每个测试都会将页面截图与这个基准进行比较:

图片 1

啊哈!要是这么简单就好了。我尝试过这个方案,结果遇到不少问题,最后不得不放弃这个方案。而且可笑的是我每次修改了代码都要运行应用。主要的问题在某些技术:浏览器在呈现内容的时候存在一些细微的差异 —— 造成这些差异的因素可能来源于屏幕或者 GPU,对内容进行抗锯齿渲染的方式略有不同。没有两张截图会拥有完全一样的像素。这些差异人眼觉察不到,也就是说,按像素进行比较毫无意义。你需要使用图像分析技术来处理这个问题。

而且,还有其它问题,仅从我基于 Applitools 的工作就能总结出如下问题:

  • 你不能对整个页面截图 —— 你只能对可以看到的部分截图。
  • 如果页面中存在动画,那就不能拿它和基础图像进行比较。
  • 动态数据,比如广告,会让事情变得复杂,难以找出与基准相比的实际差异。
  • 页面什么时候才会“完全加载”?什么时候才能对其截图?现在在 DOM 加载完成时截图是不够的。要找出什么时候才可以截图是件非常困难的事情。

我们做得到

不过我们似乎可以编写自动的可视化测试。存在着无数我并不知道的工具可以更好的截图并将之与标准图像比较。其中一些如下:

这些工具可以解决全部或部分上面提到的问题。在系列的这个部分,我想向你展示如何使用 Applitools Eyes 来编写可视化测试。

写一个可视化测试

既然可视化测试是测试的最终产品,它们应该用于端到端浏览器的前端测试中。所以这是我的可视化测试。这个代码非常有意思,它比常规的端到端测试更小。它由三个部分组成 —— 设置浏览器,测试 Applitools Eyes 和测试本身。

我们再看一下 Selenium Driver 浏览器设置,它与第三部分的端到端测试相同:

let driver before(async () => { driver = new webdriver.Builder().forBrowser('chrome').build() }) after(async () => await driver.quit())

1
2
3
4
5
6
let driver
before(async () => {
  driver = new webdriver.Builder().forBrowser('chrome').build()
})
after(async () => await driver.quit())

这会打开一个浏览器并等待驱动命令。不过在开始测试之前,我们需要安装(以及拆卸)Applitools Eyes:

const {Eyes} = require('eyes.selenium') let eyes before(async () => { eyes = new Eyes() eyes.setApiKey(process.env.APPLITOOLS_APIKEY) await eyes.open(driver, 'Calculator App', 'Tests', {width: 800, height: 600}) }) after(async () => await eyes.close())

1
2
3
4
5
6
7
8
9
10
11
const {Eyes} = require('eyes.selenium')
let eyes
before(async () => {
  eyes = new Eyes()
  eyes.setApiKey(process.env.APPLITOOLS_APIKEY)
  await eyes.open(driver, 'Calculator App', 'Tests', {width: 800, height: 600})
})
after(async () => await eyes.close())

我们创建了一些新的 Eyes(第5行),并打开它们(第8行)—— 可爱的术语,不是吗?不要忘了从 Applitools 获取一个 API 的 Key,这是我们会在下一小节讨论的东西,然后把它设置给 Eyes(第6行)。

现在我们已经设置好浏览器和 Eyes,我们可以写测试了,这和我们的端到端测试非常像:

it('should look good', async function () { await driver.get('http://localhost:8080') await eyes.checkWindow('Initial Page') const digit4Element = await driver.findElement(By.css('.digit-4')) const digit2Element = await driver.findElement(By.css('.digit-2')) const operatorMultiply = await driver.findElement(By.css('.operator-multiply')) const operatorEquals = await driver.findElement(By.css('.operator-equals')) await digit4Element.click() await digit2Element.click() await operatorMultiply.click() await digit2Element.click() await operatorEquals.click() await eyes.checkWindow('After calculating 42 * 2 =') })

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
it('should look good', async function () {
   await driver.get('http://localhost:8080')
   await eyes.checkWindow('Initial Page')
   const digit4Element = await driver.findElement(By.css('.digit-4'))
   const digit2Element = await driver.findElement(By.css('.digit-2'))
   const operatorMultiply = await driver.findElement(By.css('.operator-multiply'))
   const operatorEquals = await driver.findElement(By.css('.operator-equals'))
   await digit4Element.click()
   await digit2Element.click()
   await operatorMultiply.click()
   await digit2Element.click()
   await operatorEquals.click()
   await eyes.checkWindow('After calculating 42 * 2 =')
})

这个系列的前一篇文章中的端到端测试相比,你可以看到它很像,但更短。代码中主要的区别是对特定元素的验证被一行简单的代码代替了:

await eyes.checkWindow(‘’)

1
await eyes.checkWindow(‘’)

在端到端测试中,我们是这样做的:

await retry(async () => { const displayElement = await driver.findElement(By.css('.display')) const displayText = await displayElement.getText() expect(displayText).to.equal('0') })

1
2
3
4
5
6
await retry(async () => {
  const displayElement = await driver.findElement(By.css('.display'))
  const displayText = await displayElement.getText()
  expect(displayText).to.equal('0')
})

我们通过重试等待页面“稳定”。但进行可视化测试的时候,你不需要等待页面可见 —— eyes.checkWindow 会帮你干这个事情!

eyes.checkWindow 会截取页面图像并将之与前端测试产生的基准图像进行比较(参阅下面的小节“运行可视化测试”)。如果比较结果是新图像与基准等价,则测试成功,否则测试失败。

可视化测试是端到端测试更好的工具

进行可视化测试的巨大好处是 —— 系统处理的稳定性。而且 —— 你不是只检查一两个元素 —— 你是在一次断言中检查整个页面。你可能会发现一些压根没想去找的问题!

总的来说,看起来可视化测试是端到端测试中唯一的断言方法。但不幸的是,目前可视化断言较慢,所以你需要好好地把一些检查特定元素的常规断言和检查整个页面的可视化断言组合起来。

记住 —— 没有灵丹妙药:没有某一个测试类型可以做所有事情!混合不同类型的测试可以更好的建立平衡,建议这样的混合需要测试经验。所以现在就开始测试!的确,测试需要时间和责任。但是一旦你开始测试,你就不能回头了。

运行可视化测试

我们怎么才行运行可视化测试更看到结果?

如果你没有使用环境变量 APPLITOOLS_APIKEY 来提供一个 API Key,npm test 就会跳过可视化测试。所以需要获取一个 API Key 来运行测试,去 Applitools 注册个用户就好。你可以在你的 Applitools 账户界面找到 API Key。把它拷贝下来,用到测试中去(在 Linux/MacOS 中):

APPLITOOLS_APIKEY=<the-api-key> npm test

1
APPLITOOLS_APIKEY=<the-api-key> npm test

如果你使用的是 Windows,那么:

set APPLITOOLS_APIKEY=<the-api-key> && npm test

1
set APPLITOOLS_APIKEY=<the-api-key> && npm test

完成后就可以进行测试了。第一次测试会失败并报告错误 EYES: NEW TEST ENDED。

图片 2

这是因为还没有用于比较的基准。另一方面,如果你看看 Applitools Eyes 界面,会看到:

图片 3

从 Applitools 来看,测试通过了,因为这是一个基准,它假设基准是正确的。你可以通过界面上每个截图的“Like(像)/Unline(不像)”使其“失败”。

第二次运行 npm test,测试会成功:

图片 4

Applitools 界面也会显示为:

图片 5

如果我们故意让测试失败,(比如)通过点击 43 * 3 而不是 42 * 2,测试会失败,Applitools 界面会显示测试并高亮不同之处:

图片 6

修复这个“Bug”需要在 Mocha 和 Applitools 中让测试再次通过。

小结

这里对测试前端代码的系列进行一个总结。如果你觉得我遗漏了什么,或者有其它的问题/评论/吐槽,请推@giltayar,或者回应本文。

我必须承认自己很想在这个系列中再多写一篇文章 —— 关于测试包含 Ajax 调用的应用,实际的应用程序都会有些需要。

谁知道呢?

1 赞 2 收藏 1 评论

图片 7

本文由俄罗斯贵宾会发布于Web前端,转载请注明出处:测试你的前端代码:可视化测试

您可能还会对下面的文章感兴趣: