返回博客

如何真正地测试 UI

领先工程团队使用的测试技术

loading
Varun Vachhar
@winkerVSbecks
最后更新

测试 UI 很棘手。用户期望频繁发布包含各种功能的版本。但是每个新功能都会引入更多 UI 和新的状态,然后您必须对其进行测试。每种测试工具都承诺“简单、不脆弱、快速”,但在细则中都有权衡取舍。

领先的前端团队是如何跟上步伐的?他们的测试策略是什么,他们使用什么方法?我研究了 Storybook 社区的十个团队,以了解哪些方法有效——Twilio、Adobe、Peloton、Shopify 等。

这篇文章重点介绍了规模化工程团队使用的 UI 测试技术。这样,您就可以创建一个务实的测试策略,以平衡覆盖率、设置和维护。在此过程中,我们将指出要避免的陷阱。

我们正在测试什么?

所有主要的 JavaScript 框架都是组件驱动的。这意味着 UI 是从“自下而上”构建的,从原子组件开始,逐步组合成页面。

请记住,UI 的每一部分现在都是一个组件。是的,包括页面。页面和按钮之间的唯一区别在于它们如何使用数据。

因此,测试 UI 现在与测试组件同义。

当涉及到组件时,不同测试方法之间的区别可能很模糊。与其关注术语,不如考虑 UI 的哪些特性值得测试。

  1. 视觉: 给定一组 props 或状态,组件是否正确渲染?
  2. 组合: 多个组件是否协同工作?
  3. 交互: 事件是否按预期处理?
  4. 可访问性: UI 是否可访问?
  5. 用户流程: 跨各种组件的复杂交互是否有效?

您应该关注哪里?

全面的 UI 测试策略需要平衡精力和价值。但是有很多测试方法,因此很难确定哪种方法适合任何给定的情况。这就是为什么许多团队使用以下标准评估不同的测试技术。

  • 💰 维护成本: 编写和维护测试所需的时间和精力。
  • ⏱️ 迭代速度: 从进行更改到看到结果之间的反馈循环有多快。
  • 🖼 真实环境: 测试执行的位置——在真实的浏览器中还是在像 JSDOM 这样的模拟环境中。
  • 🔍 隔离失败: 测试失败,您能多快确定失败的根源。
  • 🤒 测试不稳定: 误报/误判会破坏测试的目的。

例如,端到端测试模拟“真实”用户流程,但不适用于所有地方。在 Web 浏览器中进行测试的主要优势也是一个劣势。测试运行时间更长,并且存在更多失败点(不稳定!)。

现在我们已经介绍了要测试的 UI 特性和评估每种测试方法的标准,让我们看看团队如何设计他们的测试策略。

“测试让我对自动化依赖更新充满信心。如果测试通过,我们就合并它们。”

Simon Taggart,Twilio 首席工程师

视觉测试:这个看起来对吗?

现代界面有无数的变化。您的变化越多,就越难确认它们在用户设备和浏览器中都能正确渲染。

过去,您必须启动应用程序,导航到页面,并进行各种扭曲才能使 UI 进入正确的状态。

组件结构允许您将特定变体渲染为 props 和状态的函数。您无需启动整个应用程序即可查看组件的渲染方式,而是传入 props 和状态以隔离查看它。

TwilioShopify 使用 Storybook 来隔离组件,模拟它们的变体,并将支持的测试用例记录为“故事”。这允许开发人员在初始开发期间以及在 QA 中再次进行组件外观的抽查。

尽管如此,考虑到应用程序的规模,手动测试 UI 外观是不切实际的。每当您调整 UI 时,都必须检查每个组件的变体在每个断点和浏览器中的情况。这是一项非常大的工作!

Auth0Radix UI 自动化了 UI 验证过程。他们使用视觉测试来捕获每个 UI 组件的屏幕截图,包括标记、样式和其他资产,都在一致的浏览器环境中。这样,他们正在测试用户实际看到的内容。

每次提交,新的屏幕截图都会自动与先前接受的基线屏幕截图进行比较。当机器检测到视觉差异时,开发人员会收到通知,以批准有意的更改或修复意外的错误。

但是 DOM 快照测试呢?评估 HTML blob 的缺点已经被充分 记录

值得吗?

总是值得的。视觉测试具有高价值和低成本。它们只需要最少的维护工作,在真实的浏览器中执行,并且不稳定性低。

组合测试:这个能一起工作吗?

当组件组合在一起时,往往会发生奇怪的事情。UI 由许多简单的组件组成。验证这些组件如何集成可确保系统作为一个整体正常工作。

但是测试组合很棘手,因为复杂的功能通常连接到数据和应用程序状态。这需要您模拟或仿真应用程序的业务逻辑。

BBCSidewalk Labs (Google) 使用 Storybook 来隔离构建组合组件。Storybook 的插件简化了模拟数据、事件和 API 响应。一旦您的 UI 在 Storybook 中隔离,您就可以进行视觉测试,以验证组件集成,一直到页面。

值得吗?

通常值得。这些测试需要一些投入,但它们会揭示非显而易见的集成问题,否则很难追踪。

交互测试:当我按下这个按钮时会发生什么?

界面不是静态的。用户可以与 UI 交互,填写表单字段并触发事件。

您如何确保 UI 正在正确响应交互?我们可以使用计算机来模拟和验证用户交互!

一种方法是使用像 Enzyme 这样的工具来访问组件的内部方法。然后触发状态更改并检查结果。它有效,但最终您测试的是内部工作原理,而不是用户与 UI 交互的方式。

这就是为什么大多数团队现在使用 Testing-Library,因为它评估组件的输出。它的工作原理是在虚拟浏览器 (JSDOM) 中渲染整个组件树。它提供了模仿真实世界用法的实用程序。

将 Storybook stories 与 Testing Library 结合使用

Adobe 旨在通过将组件用例编写为 stories 来进一步迈进。然后在 Jest 中重用它们来运行交互测试。这由 Component Story Format 启用——一种基于 JavaScript ES6 模块的可移植格式。因此,允许您在开发期间以及在视觉、组合和交互测试中再次使用相同的 story。

值得吗?

有时值得。交互测试确保组件之间的连接正常工作。事件正在流动,状态正在更新。在实践中,这意味着您可以通过编写相对低维护成本的测试来获得适度的覆盖率。

可访问性测试 – 应用程序是否适用于所有用户?

您的用户以各种方式与 UI 交互。例如,使用鼠标、触摸屏、键盘和屏幕阅读器。可访问性是使网站对所有人可用的实践。

测试可访问性的最准确方法是在浏览器、设备和屏幕阅读器的组合中手动检查它。公司通常聘请外部顾问或培训内部人员。但这可能是不切实际的,因为手动测试每次 UI 更改都非常耗时。这就是为什么团队使用混合方法,将手动测试和自动化相结合。

作为 QA 的第一道防线,使用机器来捕获明显的违反可访问性的情况。这通过针对一组最佳实践启发式方法(例如,使用像 Axe 这样的库)审核渲染的 DOM 来实现。在自动检查完成后,手动抽查 UI 以查找细微的问题。

结合自动化和手动最终成为覆盖率和精力的务实平衡。您获得了一个快速的反馈循环,您可以在可访问性问题影响生产之前找到并修复它们。大多数团队使用 Axe 对组件运行自动检查。这也使他们能够执行有针对性的测试以更快地发现错误。例如

  • 原子组件: 评估键盘感知、不良的颜色对比度或丢失的 aria 属性。
  • 组合: 验证组合组件不会相互妨碍行为。
  • 页面: 确保所有标题和各个部分都以正确的顺序出现。

Twilio Paste 团队使用 jest-axe 集成在组件上运行自动可访问性审计。Axe 也可用作 Storybook 的插件

值得吗?

总是值得。这不仅对您的用户有好处,而且也是法律要求。Axe 是一种低投入的工具。使用它不会自动使您的应用程序可访问,但它可以及早捕获许多问题。

用户流程测试 – 您的应用程序是否端到端工作?

即使是最基本的任务也需要用户完成跨多个组件的一系列步骤。这是另一个潜在的故障点。像 CypressPlaywright 这样的工具允许您对完整的应用程序运行端到端 (E2E) 测试,以验证此类交互。

测试完整的应用程序需要大量的基础设施工作。您必须创建一个测试环境,该环境并排部署系统的所有部分——前端、后端和其他服务。种子测试数据。然后连接到云浏览器以实际运行测试。

鉴于这些权衡,大多数团队选择放弃对其 UI 进行全面的 E2E 测试,而是倾向于交互和组合测试。或者他们将自己限制为一小部分 E2E 测试,以确保应用程序在部署到生产环境继续工作。

但是,对于某些团队来说,这种权衡是值得的。例如,O'Reilly 使用 Docker 来启动他们的整个基础设施。然后使用 Cypress 运行 E2E 测试以验证用户旅程。

值得吗?

谨慎使用。E2E 测试需要大量的权衡。它们提供高度的信心,但需要时间和精力来启动和测试整个系统。因此,将 E2E 测试限制在关键用户流程上,例如,注册 → 添加到购物车 → 购买。

自动化枯燥的部分

如果您像我一样是开发人员,那么构建 UI 比测试每个状态更有趣。那么您如何测试每个功能,并且仍然有时间编写代码呢?

我采访的每个团队都使用持续集成 (CI) 服务器来减少人工工作。每次您推送代码时,CI 都会自动触发您的测试套件。测试在后台执行,结果报告给 pull request 以供大家审查。

自动化 CI 检查自动检测 UI 错误,以便在部署到生产环境之前让您对 UI 的“外观和感觉”充满信心。

您的 UI 测试策略

UI 测试是交付高质量体验不可或缺的一部分。确定务实的测试策略可能会令人困惑,因为应用程序的表面积很大,并且有很多测试方法。

您最终需要权衡取舍。有些测试易于维护,但提供虚假的保证。另一些则将系统作为一个整体进行评估,但速度很慢。

在采访了十个团队以确定哪些 UI 测试方法实际有效后,我整理了他们推荐的工具的简短列表。

  • 📚 Storybook 用于将组件与其上下文隔离,以简化测试。
  • Chromatic 用于捕获原子组件中的视觉错误,并验证组件组合/集成。
  • 🐙 Testing Library 用于验证交互和底层逻辑。
  • ♿️ Axe 用于审核可访问性
  • 🔄 Cypress 用于验证跨多个组件的用户流程
  • 🚥 GitHub Actions 用于持续集成

下表总结了每种 UI 测试方法的优缺点以及使用频率。

到目前为止,本文仅触及了 UI 测试的表面。在即将发表的文章中,我将更深入地研究测试堆栈的每一层,并深入了解如何实施 UI 测试策略的机制。加入邮件列表,以便在新测试文章发布时收到通知。

如何评估不同的测试方法

加入 Storybook 邮件列表

获取最新新闻、更新和版本

6,730位开发者及更多

我们正在招聘!

加入 Storybook 和 Chromatic 背后的团队。构建被数十万开发人员在生产环境中使用的工具。远程优先。

查看职位

热门文章

用于 CSS 的 Storybook 插件

用于样式化组件的更好工作流程
loading
Varun Vachhar

Storybook 中的视觉测试

了解如何自动查明 UI 错误
loading
Varun Vachhar

Storybook 6.2

面向未来的组件开发
loading
Michael Shilman
加入社区
6,730位开发者及更多
为什么为什么选择 Storybook组件驱动的 UI
文档指南教程更新日志遥测
社区插件参与进来博客
案例展示探索项目组件词汇表
开源软件
Storybook - Storybook 中文

特别感谢 Netlify CircleCI