无障碍测试
您将学习到
- 确保应用程序对残障用户可用的策略
- 通过插件与Cypress无障碍功能提供的无障碍扫描有何区别
- 测试中无障碍检查的性能影响
- 如何编写专门的无障碍测试
- Testing Library定位器与测试ID的 区别
无障碍测试有助于确认应用程序对残障用户能否正常工作。
为了奠定良好的无障碍用户体验基础,网站和应用必须符合特定指南,即网页内容无障碍指南(WCAG)。达到或超越这些指南将确保您的残障用户能够独立感知应用内容、浏览页面和区域,并完成可用操作。
Cypress通过标准测试实践、丰富的插件生态系统以及Cypress无障碍功能(Cypress Cloud中的商业企业级解决方案)支持多种无障碍测试。
在Cypress测试中纳入无障碍考量
以下是使用Cypress测试时考虑无障碍的主要方式:
无障碍扫描
Cypress Accessibility 是一项付费高级解决方案。立即预约演示,了解如何轻松增强您的无障碍测试,同时加速开发流程。
明确的、应用特定的测试
- 专注无障碍的断言和定位器
- 针对辅助技术相关特定功能的测试
下文将逐一讨论这些方法。
无障碍扫描
自动化扫描非常有效,因为许多无障碍问题是由错误的HTML结构或辅助技术(如屏幕阅读器、语音控制系统、盲文显示器等)所需数据缺失引起的。浏览器将页面上的当前HTML转换为标准化格式供其他技术接入。测试中的自动化扫描会在这一过程所需特定项目缺失时发出警报。
请注意,虽然自动化扫描能很好地检测已知规则集的违规情况,但没有任何自动化扫描能证明界面完全无障碍且对残障用户友好。始终需要了解所选库的局限性和预期覆盖范围,然后根据用户需求,通过手动测试和/或传统Cypress断言来补充覆盖空白。
测试中插件
cypress-axe
插件是一个社区插件,它将Deque Systems开发的流行Axe Core®库集成到Cypress测试中。
设置插件后,项目中会添加命令来注入该库并运行无障碍检查。运行包含的checkA11y()
命令会对当前测试页面或组件的状态进行扫描,您可以选择在检测到无障碍问题时使测试失败。详细配置可用于限定您想要测试的特定WCAG成功标准及相关规则。
还有一些基于cypress-axe
构建的新社区插件以各种方式扩展其功能,如wick-a11y
和cypress-a11y-report
,以及其他无障碍测试库如IBM Equal Access Checker。这些工具都有各自的安装、设置和执行检查的文档,此处不再赘述。
通用的"添加命令触发扫描"方法有助于检测和预防常见问题,如颜色对比度差、图标和按钮标签缺失、图像缺少alt文本等可通过通用检查发现的用户界面实现错误。
管理测试性能
测试中自动化无障碍检查非常有价值,因为它们将大量关于各种规则和标准的断言捆绑到一个简单命令中。但这也意味着它们会带来一些开销:例如,每次调用cy.checkA11y()
都会评估DOM元素以确定哪些无障碍规则适用于页面中的每个元素,然后为这些元素运行特定的DOM检查,并计算结果,所有这些都需要时间完成。如果同时生成截图等其他资源,也应考虑其性能影响,并仅在需要时生成资源。
通常,如果无障碍检查数量较少,这不是问题,但随着无障碍测试规模的扩大,需要对复杂应用和工作流的数百甚至数千种独特状态进行检查时,这可能成为管道总执行时间的主要贡献者。由于无障碍检查往往是逐步添加的,所花费的时间通常不明显,但绝对值得关注。
为避免性能膨胀,您需要积极管理测试性能与测试执行频率之间的权衡。有时通过仅测试初始页面加载或测试结束时的状态来解决, 但这种方法会遗漏许多重要状态,如模态框、多步骤工作流、表单错误状态、菜单打开状态等。由于许多测试可能与其他测试开始或结束于相同的页面状态,因此可能存在大量冗余扫描,因此更有针对性地进行测试会带来回报。
还可以通过将无障碍检查限定为仅针对特定规则或页面特定部分,或将其限制在组件测试中来管理性能。应培训测试人员如何以及何时运行无障碍检查,以获得最佳反馈,同时消除不增加价值的冗余检查,并最小化对测试管道的干扰。
最好主动管理这一点,因为与无障碍检查相关的不必要的波动、失败或超时可能会引起挫败感,并导致对这种测试形式的抵制,进而更难实现无障碍目标。
Cypress无障碍功能
测试中无障碍检查是典型测试场景中唯一可用的类型。它们带有一些限制和权衡,而Cypress无障碍功能(Cypress Cloud中提供)旨在解决这些问题。通过将检查移出测试上下文并在记录测试时在Cypress Cloud中运行,Cypress无障碍功能消除了可能阻碍测试中检查有效实施的采用、培训和测试性能障碍。Cypress自动检测用户流中的所有步骤,无需编写测试代码。
要了解更多信息,您可以阅读我们的专用文档,或查看Cypress Realworld App演示项目中的自动生成无障碍报告公开示例。
Cypress Accessibility 是一项付费高级解决方案。立即预约演示,了解如何轻松增强您的无障碍测试,同时加速开发流程。

专门的无障碍测试
虽然像Axe Core®这样的自动化工具可以检测缺失属性和其他影响残障人士使用网络体验的代码质量问题,但这种自动化对您的特定应用及对用户的期望一无所知。这就是在规范中包含无障碍考量的用武之地。
键盘导航
要测试页面内的键盘导航,您可以使用cy.press()
来分发原生tab事件。这也可用于测试自动完成等自定义行为。
断言图像的替代文本
要为徽标图像断言正确的替代文本是否存在,可以编写明确的测试:
it('adds todos', () => {
cy.visit('https://example.cypress.io/')
// 明确检查图像的alt文本
cy.get('img[data-cy="logo"]').should('have.attr', 'alt', 'Cypress Logo')
})
也可以使用无障碍感知定位器方法在执行其他断言时查找元素。这里我们没有使用元素的测试ID,而是通过其alt
文本定位图像。这更简洁,选择哪种格式取决于团队的偏好:
// 使用`alt`内容定位图像
cy.get('img[alt="Cypress Logo"]').should('be.visible')
这种无障碍友好的定位器方法也可以通过Cypress Testing Library插件实现,该插件为此提供了一些辅助工具:
// 使用推荐的ByRole Testing Library定位器
cy.findByRole('img', { name: 'Cypress Logo' }).should('be.visible')
断言按钮的可访问名称
类似的无障碍思维定位器技术可用于按钮等交互元素:
// 点击通过`cy.contains()`定位的"提交"按钮
cy.contains('button', 'Submit').click()
使用Testing Library的ByRole
定位器:
// 点击任何具有`button`角色且可访问名称为`Submit`的元素
cy.findByRole('button', { name: 'Submit' }).click()
在定位特定HTML元素本身与仅通过role
定位这些相同元素之间存在一些重要区别,这是Testing Library的主要建议。我们将在下一节讨论这些区别。
测试ID、Testing Library与无障碍
使用data-cy
风格的测试ID属性来帮助提高测试稳定性一直是Cypress长期以来的最佳实践建议。测试ID对非功能性UI更改具有弹性,因为它们不指定有关代码或内容本身性质的任何信息,仅表明存在具有该数据属性的元素。当代码更改时,只要data-cy
属性保留在正确位置,使用它们的所有测试应继续通过。
这种方法明确避免测试无障碍性——这完全关乎被测试内容的性质和结构,以及代码实现与该内容的匹配程度,以在各种辅助技术和浏览器设置中提供功能性体验。
Testing Library(2018年推出,现已广泛流行)有时被视为解决显式测试ID不提供任何无障碍测试好处这一问题的方案。虽然Testing Library的辅助工具可能方便且有用,并使测试人员始终关注无障碍性,但重要的是要注意Testing Library定位器不保证被测试元素的无障碍性。
无论您 主要使用Testing Library元素定位器、测试ID还是其他方法,测试无障碍性都需要对应用程序的实现和行为做出特定断言。
这一主题的内容远超我们在此能涵盖的范围,但我们将提供一个小示例和建议。
关于角色与元素的断言 - 按钮示例
原生HTMLbutton
元素具有浏览器为键盘和屏幕阅读器用户实现的复杂无障碍契约。以下是浏览器自动管理的按钮元素的部分方式列表:
- 它具有隐式
button
角色,以便用户知道它是什么 - 例如,屏幕阅读器会将其宣布为按钮 - 它具有默认浏览器按钮样式,以在视觉上与周围内容区分
- 它具有默认浏览器悬停和"按下"状态样式
- 它位于文档的tab顺序中,可以通过键盘聚焦
- 聚焦时它会获得焦点轮廓样式
- 它可以通过鼠标点击、回车键或空格键激活
- 如果放置在
form
元素内,通过任何这些方法激活按钮都会提交表单(因为其默认类型为submit
) - 在Windows高对比度模式(某些视觉障碍人士使用)下,它将接收特定的、用户可自定义的样式
另一方面,具有button
角色的div
不会获得任何默认浏览器无障碍行为,在没有自定义JavaScript和CSS替换浏览器契约的情况下不可访问。
这意味着,如果没有对button
元素本身或该元素的无障碍"契约"的完整测试进行一些断言,开发人员从button
重构为<div role="button">
是不安全的,即使Testing Library在使用ByRole
定位器时会将两者视为相同。这是因为,与测试ID类似,ByRole
方法旨在_避免_直接测试实现,以在代码重构时保持测试的弹性。
不熟悉无障碍性的开发人员可能会认为,如果Testing Library的ByRole
定位器可以在代码更改前后通过,则底层元素的功能或无障碍相关没有变化。如我们所见,事实并非如此,因为浏览器仅对原生HTML元素实现的额外行为。有关此差异及为何首选语义HTML元素的更多信息,请参阅可访问富互联网应用(ARIA)的第一条规则。
在哪里测试无障碍性
那么,在测试自动化中应该做些什么来帮助确认UI的无障碍性?首先,对于已知关键区域(如表单或结账流程),确保至少在一个地方明确测试无障碍行为。这意味着验证表单字段和按钮是否具有正确的标签并使用预期的HTML元素,以及传达必要信息的DOM的其他方面。
组件测试是进行这种集中无障碍规范工作的绝佳场所,无论是使用Cypress组件测试还是其他工具。组件测试在开发期间本地运行,由开发人员在构建UI时编写,可以轻松指定预期呈现的特定HTML,而不会分散对特定用户流的端到端测试的注意力。
至少应对给定组件、应用区域或工作流进行一次无障碍测试。一旦实现这一点,除非这些测试引入未在其他地方进行无障碍测试的新组件组合,否则在其他 测试中重复断言相同内容的子集不会带来额外的无障碍好处。
选择定位器方法
测试ID是最具弹性的定位器选项,是最大化管道稳定性的良好选择,特别是如果端到端测试由不熟悉无障碍性的人员编写,并且不知道应预期的正确角色、元素和行为。只要通过断言明确测试无障碍性,并使用像Axe Core®这样的库来捕获错误,您不会失去任何无障碍"覆盖"。
Testing Library定位器方便且为许多React开发人员所熟悉(由于其起源为"React Testing Library"),且不需要任何代码更改,但当标签缺失时,可能会导致_许多_测试失败,而不仅仅是您的明确无障碍断言,因为它们更接近实现细节。
此外,Testing Library定位器可能会给人一种错误的信心,认为某物是可访问的,仅仅因为它可以通过角色定位。尽管如此,当正确理解时,团队可以使用这种方法编写有效的测试,并且像findByLabelText
这样的定位器特别有用。
在所有无障碍自动化讨论中,最重要的是:您的测试策略如何最好地支持残障用户独立理解和使用您的应用程序?Cypress使您能够将用户置于测试过程的中心。通过混合自动化扫描和一些特定的有意断言,您可以高度确信您的应用程序没有已知的无障碍错误,并让测试管道在出现偏差时警告您。