为什么是e2e测试
总结:e2e 是低投入、高回报的
我一直认为前端 e2e 测试是低投入、高回报的:
其一,开源社区已经有比较强大的 e2e 测试框架生态
-
框架层面 :如 puppeteer、cypress、playwright 等基于各种浏览器操作 API 封装的框架,很多还是跨平台的,如 chromium (chrome)、webkit(safari)。
-
周边工具 :覆盖率、视觉回归、可读性强的测试报告等,大多数框架都开箱即用地支持这些功能,社区也有相关的实现。
基于已有的生态,秉着拒绝重复造轮子的原则,大部分情况下 不必接触测试框架底层、以及自主研发各种周边工具 ,只需要用好框架、录制或编写测试脚本即可。
其二就是 e2e 的特性,和单元测试不同,我们会把项目的内部逻辑看成一个黑盒,测试框架只是像我们普通用户一样操作页面,只关注功能、视觉方面,其行为更贴近于用户。
也就是说,成本较代码层面的单元测试会低很多,开发者要做的只是写写操作脚本就可以了 (提示:很多框架附带有脚本自动化生成工具,可以将你的操作流程生成脚本),并且对于业务代码的收益也不逊于单元测试。
意义
释放人力成本、降低潜在风险
由于开发者的逻辑设计、或者业务本身的复杂性,很可能出现下面的情况:
-
在项目立项的首次需求落地,开发者会根据 PRD 考虑所有产品、UI 的 case 并加以实现与自测。QA 同学在走测试时也会根据需求文档去逐一试验所有的 case。
-
但在此之后若有一个小的迭代或者 bug fix原则上来说开发、UI 以及测试同学都应该像首次上线前一样,把所有的 case 再走一遍。
-
但现实上由于各种各样的因素(排期、工作量等),无法做到像首次迭代那样面面俱到,开发测试同学可能只会去考虑本次迭代的内容。而我们无法保证本次修改没有影响到之前的逻辑,很可能会出现新的 bug,即出现”牵一发而动全身”的局面。
做好完备的 e2e 测试是解决上述问题的最佳实践。
核心流程
首先用一张图来描述一下 e2e 测试的核心流程:
按照产品功能编写脚本
当前端开发者开发完页面,就可以依照产品的交互流程将所有的 case 编写成脚本。编写的脚本主要要考虑以下问题:
-
覆盖产品 核心 交互流程。(不同的 URL 参数、不同的操作路径都应该分开测试)------ 功能测试 。
-
在关键业务节点 进行截图并生成 (初次生成的截图称为 baseline )以供报告收集和 Image Diff (当前 UI 截图和已有 baseline 对比)------ 视觉测试 。
- 对整个操作过程进行 屏幕录制 以便查看或验收。
在本地环境下执行测试
脚本编写完成之后就可以执行测试,如果和期望有偏差,开发者可以自行回归并修改。
值得注意的是,不同浏览器和平台的截图因呈现方式、字体等因素会有偏差,而我们的 image diff 是精确到像素级的,所以对于不同平台需要不同的截图,并且本地生成快照的环境和 CI 环境下执行的环境必须完全一致 。
如何保证本地环境和 CI 环境一致?
我们可以使用容器镜像工具 docker,只需要在 CI 平台和本地生成快照时使用相同的 docker 镜像即可,另外基本上流行的 e2e 测试框架都封装了最佳实践的 docker 镜像,所以我们无须手动编写 docker 相关的配置文件。
另外,本地更新快照时开发者应该 对docker的存在无感 ,开发体验需要和直接执行测试命令一样 ,这也是我们需要重点考虑的。
执行 CI 流水线、生成报告
本地调试完成确认无误后即可将脚本和 baseline 推送到远程仓库中,准备进入 CI 环境。在测试完成之后可以测试报告以供相关同学查看,报告内容应该包括测试覆盖率、通过情况、错误堆栈、截图信息、视频录制文件等。
和单元测试不同,e2e 测试在无头浏览器中执行,会更消耗性能,所以要利用 多机并行机制 提高测试效率,目前常用的并行机制有:
- 服务调度型: 维护一个 DashBoard 调度平台,各个 CI 机器执行前和 DashBoard 通信(通过一个 id 来区分同一个测试),通信内容包括机器的配置、环境等,DashBoard 通过实现一个灵活的 负载均衡 算法,为各个机器分配不同的任务,执行后上报,由 DashBoard 汇总并处理。优点是方便管理,因为所有的测试结果会被统一收集,并且 兼顾了测试机器的本身特性 ,缺点就是 开发成本高 ,并且在单个 CI 平台下,各个机器配置不同的情况比较少。
- 固定分片型: 固定分片不需要维护调度平台,它通过 传参 的形式,利用一个 固定的负载均衡算法 ,指定当前机器执行哪一部分,优点是开发成本低,缺点是无法兼顾各个机器 CI 性能不一致的问题:
测试回归
如果有新的需求或者修复了 bug,那么就需要重新执行所有的测试,利用 CI 卡点确保原先的功能回归无误、视觉回归无误。
如有必要,那么可以让测试框架更新相应的 baseline。这个操作是 比较危险 的,设想一下:现在有两个 case 出现了 Image Diff 异常:第一个是预期的 UI 修改,第二个是存在的 bug,我们想更新第一个,开发者很有可能不小心进行全量操作将第二个也一起更新,从而 让 bug 变成了 baseline。
所以在执行快照更新中要运用收到严格约束case 的数量 ,一般来说 只能有一个, 即做到逐一比对更新,确保 baseline 都是符合预期的
开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 15 天,点击查看活动详情