[缘起] 前端 E2E 测试的困境

与其它自动化测试不同,前端的 E2E 测试一直是个老大难问题,难点主要在于 如何描述测试

自动化测试的核心是检查特定输入能不能得到符合预期的结果。对于单元测试和 API 测试来说,“特定输入”就是函数或者接口的参数,结果也是当前语言的数据类型或者通用的比如 JSON,二者一方面好描述,另一方面好验证。写起来就没什么难度。

比如

sum(a, b) {
 return a + b;
}

要验证输入 1 和 2,返回 3,则可以写成:

const assert = require('assert');
describe('sum', function() {
  it('should equal', function() {
    assert.equal(sum(1, 2), 3);
  });
});

这里输入输出都很容易描述,所以自动化测试就没什么难度。

但是 UI 的 E2E 测试并非如此。UI 是做给用户看的,所以,一个 UI 的 E2E 测试应该写成这种形式(这里拿一个类似于活动行的应用来举例子):

  1. 打开应用首页
  2. 显示活动列表
  3. 点击列表中的任一项
  4. 进入活动详情页
  5. 点击报名按钮
  6. 登记个人信息
  7. 点击付费按钮
  8. 完成付费
  9. 看到报名成功的信息

这个过程当中用户的操作,很难和程序当中的抽象产物,比如按钮、列表等产生关联。操作的结果,“进入下一页”,也很难进行进一步的校验。

所以在之前的生产实践中,大家喜欢用选择器来进行 E2E 测试,代表产品有 CypressNightwatch。我觉得,这里一方面有 jQuery 带来的使用习惯延续和思维定势;另一方面,借助 XPath,找到特定元件,进行交互操作和校验元素几乎是大家唯一的选择。

使用 CSS 选择器的方案并不完美,比如:

  1. 选择器本身,和 UI 视图可能并没有强关联,写出来的测试可读性不强,一段时间之后回头去看,很可能会看不懂。
  2. HTML 的 DOM 结构并不稳固,随着功能增减版本迭代经常发生变化,这个时候我们就要跟着修改测试用例。
  3. DOM 结构不能反应视图的真实状态,很可能会出现虽然测试通过,但实际上在用户眼里仍然是错误的表现。

那么,说了这么多不容易、其它方案的不完美,我的解决方案又是怎么样的呢?

这里请容许我卖一下关子,下次再介绍由我厂 OpenResty Inc. 打造的前端自动化工具 Navlang。


大家好,我是 Meathill,目前在 OpenResty Inc. 负责前端开发工作。今年我会利用业余时间,介绍我厂在前端方面的工作,包括各种垂直领域,比如自动化、基于 DevTool Protocol 开发、WebExtension 开发、Vue、CodeMirror、组件化等等,内容包括进展、经验、心得、踩坑、产品等。

欢迎大家关注本专栏,也欢迎大家光临我的博客:山维空间。如果你有任何疑问问题都可以在 SF 和我的博客上向我发问,我一定尽量答复。

相关推荐