Help us learn about your current experience with the documentation. Take the survey.

无障碍功能测试

何时添加无障碍测试

当向应用程序添加新视图时,请确保在功能测试中包含无障碍检查。 我们旨在为所有视图提供完整的覆盖。

在功能测试中测试的一个优势是,我们可以检查不同的状态,而不仅仅是 孤立的单个组件。

您可以在下面找到一些关于如何进行无障碍检查的示例。

空状态

某些视图具有空状态,导致页面结构不同于默认视图。 它们还可能提供一些操作,例如创建第一个问题或启用功能。 在这种情况下,请为空状态和默认视图都添加断言。

在用户交互前确保合规性

我们通常根据期望用户执行的一系列步骤进行测试。 在这种情况下,请确保尽早包含检查,在任何模拟步骤之前执行。 这样我们可以确保我们对用户的期望没有障碍。

在页面结构变更后确保合规性

用户交互可能导致页面结构发生重大变化。例如,显示模态框,或渲染新部分。 在这种情况下,在任何此类变更后添加断言。 我们希望确保用户能够与所有可用组件进行交互。

为大型测试套件创建单独文件

对于某些视图,功能测试跨越多个文件。 请查看我们的合并请求功能测试。 需要覆盖的用户交互数量太大,无法放入一个测试文件中。 因此,多个功能测试覆盖一个视图,具有不同的用户权限或数据集。 如果我们在所有测试中都包含无障碍检查,我们可能会多次覆盖视图的相同状态,并显著增加运行时间。 如果断言分散在许多文件中,也将更难确定无障碍的覆盖范围。

在这种情况下,考虑创建一个专门用于无障碍的测试文件。 将其放在同一目录中,并命名为 accessibility_spec.rb,例如 spec/features/merge_request/accessibility_spec.rb。 明确表示功能测试在单独的文件中具有无障碍覆盖,并且不需要额外的断言。在顶层块的开头下方包含以下注释:

# spec/features/merge_request/user_approves_spec.rb

# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Merge request > User approves', :js, feature_category: :code_review_workflow do
# covered by ./accessibility_spec.rb

共享示例

功能测试通常包含针对多个场景的共享示例。 如果它们仅通过提供的数据不同,但基于相同的用户交互,您可以在共享示例之外检查无障碍合规性。 这样我们只运行一次检查,节省资源。

如何添加无障碍测试

Axe 提供自定义匹配器 be_axe_clean,可以按如下方式使用:

# spec/features/settings_spec.rb
it 'passes axe automated accessibility testing', :js do
  visit_settings_page

  wait_for_requests # ensures page is fully loaded

  expect(page).to be_axe_clean
end

如果需要,您可以使用 within 将测试范围限定在页面的特定区域。

Axe 还提供特定的条款, 例如:

expect(page).to be_axe_clean.within '[data-testid="element"]'

# 仅运行 WCAG 2.1 Level AA 规则
expect(page).to be_axe_clean.according_to :wcag21aa

# 指定要跳过的规则
expect(page).to be_axe_clean.skipping :'link-in-text-block'

# 条款可以链式调用
expect(page).to be_axe_clean.within('[data-testid="element"]')
                            .according_to(:wcag21aa)

Axe 不测试隐藏区域,例如非活动菜单或模态窗口。要测试 隐藏区域的无障碍性,请编写激活或使这些区域可见的测试,然后再次运行匹配器。

您可以像运行任何功能测试一样在本地运行无障碍测试。

添加无障碍测试后,请确保修复所有可能的错误。 有关如何操作的指南,请参阅本指南。 您还可以检查Pajamas 组件文档中的无障碍部分。 如果任何错误需要全局更改,请创建后续问题并分配以下标签:accessibilityWG::product accessibility

最佳实践

如果您对相关产品领域有领域知识,在功能测试中添加无障碍检查会更容易。 但是,有一些事情可以帮助您为无障碍测试做出贡献。

从测试中查找页面

当您没有页面 URL 时,可以先在预览模式下运行功能规范。为此,在运行测试的命令开头添加 WEBDRIVER_HEADLESS=0。您还可以将其与 live_debug 配对,以在带有 :js 标签的任何测试用例中停止浏览器(请参阅测试最佳实践中的文档)。

为页面的哪些部分添加无障碍测试

在大多数情况下,您不希望测试整个页面的无障碍性。有几个原因:

  1. 我们在每个应用程序视图中都出现的元素,例如面包屑或主导航。在每个功能规范中包含它们会占用相当多的资源,并乘以本可以只做一次的事情。这些元素有自己的功能规范,这就是我们想要测试它们的地方。

  2. 如果功能规范覆盖整个视图,最佳做法是将范围限定在 <main id="content-body"> 元素上。以下是此类测试用例的示例:

     it "passes axe automated accessibility testing" do
       expect(page).to be_axe_clean.within('#content-body')
     end
  3. 如果功能测试仅覆盖页面的一部分,例如包含某些组件的部分,请将测试范围限定在该部分。如果可能,使用功能规范用于其测试用例的相同选择器。以下是此类测试用例的示例:

     it 'passes axe automated accessibility testing for todo' do
       expect(page).to be_axe_clean.within(todo_selector)
     end

测试输出不够具体

当 axe 测试用例失败时,它会输出发现的违规和涉及的元素。因为我们经常使用 Pajamas 组件, 所以元素可能是一个没有任何注释的 <div>,无法帮助您识别它。然而,我们可以利用一个事实: axe_core 规则同时用于 Ruby 测试和 Deque 浏览器扩展 - axe devTools。它们都提供相同的输出。

  1. 确保您已在所选浏览器中安装了 axe DevTools 扩展程序。有关更多信息,请参阅axe DevTools 官方网站

  2. 使用功能测试导航到您正在测试的视图。

  3. 打开 axe DevTools 扩展程序并运行页面扫描。

  4. 展开发现的问题,并使用高亮选项查看每个违规的页面元素。

已知无障碍违规

本节记录了与设计系统建议不同的违规:

  • link-in-text-block: 目前,使用 skipping 子句跳过 :'link-in-text-block' 规则以修复违规。当此问题作为问题 1444 的一部分修复,并且为 GlLink 组件添加下划线后,可以移除此子句。