前言:自动化端到端测试 What & Why

众所周知,由于前端作为一种特殊的 GUI 软件,其各种操作,功能都依赖于 多方因素(网络,用户操作,后端请求,业务逻辑,交互等),这些因素的交织使得其测试难度极高,广泛的讲,在端到端测试出来以前,绝大多数的测试 依赖于人工。

由于人工的成本高昂,且效率更低且无法保障稳定的重放,一般的,在前端我们会选择 成本 相对更小一点 的 单元测试 去保障一些 极其重要的组件 维持其工作,下面的事例是一个极其简单的单元测试。

it('button click should increment the count', () => {
  expect(wrapper.vm.count).toBe(0)
  const button = wrapper.find('button')
  button.trigger('click')
  expect(wrapper.vm.count).toBe(1)
})

通常而言,我们一般会选用一些 成熟的 / 广为接受 的断言库(Jest/Mocha/Chai)来编写测试用例,总体来看,断言库在使用上 没有显著的差异。

但是可以预见的是:单元测试对于前端而言,其 有意义并不起决定性作用,由于前端项目的特殊性,单元测试 很难 覆盖 所有的流程,且 绝大部分流程 无法用单元测试描述(指通过单元测试覆盖成本过于高昂 或 单纯通过单元测试难以描述)。

此时 E2E(端到端)测试应运而生,它可以帮助我们完成这一部分的缺失。

那么 E2E是什么呢?

通俗的描述一下 E2E 测试:

它是一种描述当用户实际使用应用时会发生什么的测试。

这也变相的描述了在前端项目中我们为什么要引入 E2E 测试,简单的讲:

端到端测试本质是验证应用中的所有层的可用性

所有层即:这不仅包括我们的 前端代码,甚至还包括 所有相关的后端服务和基础设施,它们更能代表应用的用户所处的环境。

通过测试用户操作如何影响应用,端到端测试通常是提高应用 是否正常运行的信心的关键,同时是在敏捷开发(或是任何以单周单位发布版本迭代的开发模式)中的 重要基石

换而言之:

如果没有 e2e 测试,所谓的敏捷开发只是空谈

那么我们期望提升迭代效率,保障系统稳定性,最重要的就是 尽快尽早 的引入 单元测试端到端测试

自动化端到端测试的常用方案?

那么在了解了 自动化端到端测试 对项目的重要性 以及 必要 性后,那么对于前端,其 E2E 自动化测试框架通常有以下几种:

  • cypress
  • puppeteer
  • nightwatch
  • testcafe
  • caperjs
  • selenium

通过 npm trending 我们可以简单的得出集中框架的流行程度:

简单对比一下功能

目前来看我们只需要对比 Puppeteer & Cypress 即可

Why Cypress?

在评价团队为什么要选择 cypress 而不使用 puppeteer 前,首先综合评价以下两者:

Cypress

优点:提供了 几乎全套 的 E2E 解决方案,并且 完整的 全量的 集成了相关的功能,提供了 全套的 UI 界面debugger 工具 及其 周边设施。

缺点:因为使用的不是 cdp 协议,所以 有些 API 是无法模拟 或是 模拟不佳的。

Puppeteer

优点:极其自由高度定制化,可以 任意的编排其实现,由于 cdp 协议的原因,本质上几乎 同真人操作一致。

缺点:api 相比较 cypress 要 “正规的多”,所以 编写的效率是降低的,并且由于 缺乏调试工具 以及 直观的使用界面,其对于前端开发 并没有显著的帮助。

总结

对于 2B 的业务来讲,使用 puppeteer 虽然对可用性有所提升,但是对我们的开发效率 并没有显著的提升,但是使用 Cypress 确实可以 显著提升开发效率的同时保障可用性

这主要由于以下一个重要的原因:Cypress 提供了一个 完整的 Dom 回放机制一套完整的 Debug 工具链

在前端对接 API 阶段,通过 Cypress 简洁的 API 加上其 特有的 debug 工具,本质上编写一个 E2E 对前端开发来讲 并不是负担。

对于前端而言,只是将原先在浏览器上 手动点击的操作 更换成了 自动的代码,同时还附带的 debug 的回放。这对于编程效率和编码体验是 极其巨大的提升,且因 E2E 测试带来的 成本被抹平了

而对于 2B 业务而言,原生的某些操作频率是极其低的,而这一部分相关的功能可以 由 QA 补足。

另外大家可能会提及性能,我们可以看到 Puppeteer 的单步测试性能几乎是 cypress 的 7x 之多,但是等到 test 套件的时候差距却缩短到了 20%不到,这其实不难理解。

E2E 测试本身是一个 等待大于运算 的应用场景,性能在这一场合下,并不会带来显著的差异,而 CI 自动化测试 可以通过 并行运行 来极大的提升效率,而这一点在 Puppeteer 甚至需要需要自行实现。

事实上对于前端开发,我们不能忽略这样一个事实:

启动效率的差异对于前端开发过程中可以忽略不计

在开启 devserver 后,前端 几乎不会关闭测试环境,而 cypress 在应用中,本质上取代了 devserver 以及 chrome 运行时环境,这带来了一个极其显著的优势:

最终的结果是反而 节省 了 测试,开发,联调三者的总时长。这些都是 Puppeteer 所 无法实现的,而且是前端 2B 业务所 迫切需求的。

不使用 puppeteer 造成的矛盾点

测试用例的割裂

不使用 puppeteer 会使得前端的用例同 QA 的用例分离开来,因为 puppeteer 的用例编写 同 cypress 完全不一致,其势必将导致双方将无法共享测试用例。

但是测试用例的割裂理论上并不会大幅度影响双方的体验主要有以下几个原因:

前端自身编写的 e2e 仅仅只是完整 e2e 的一个子集

相比较完整的 测试编写的用例,前端的用例很大程度上不会包含分支情况,这将带来一个显著的区别就是用例的量会相差的很多,前端编写的只是 QA 编写的一个最小精简子集。前端编写的 e2e 相对考虑的范畴在于:程序本身的流程正确性上,其对于周边的某些牵连功能不会面面俱到本质上双方可以借鉴复用的功能点应当不多。

前端编写的 e2e 测试的变更频率相较之测试会更频繁

不同于 QA 编写的用例,在开发阶段,e2e 测试的变更频率会相对较高,而 QA 开始编写的阶段, 其 功能 和 界面 通常已经进入稳定阶段,通常不需要频繁的变更,这对开发工具链的要求截然不同,对于前端期望的是更快的开发效率和更高效简洁的工具链。

本文标题:前端自动化端到端测试选型概述

永久链接:https://iceprosurface.com/code/web-frontend/e2e-test/

作者授权:本文由 icepro 原创编译并授权刊载发布。

版权声明:本文使用「署名-非商业性使用-相同方式共享 4.0 国际」创作共享协议,转载或使用请遵守署名协议。

查看源码: