返回博客

使用 Storybook 自动化辅助功能测试

使用 Accessibility 插件在开发期间运行检查,并使用测试运行器捕获回归

loading
Varun Vachhar
@winkerVSbecks
最后更新

辅助功能是一种使应用程序对所有人可用的实践。这意味着确保你的应用程序与辅助技术兼容,支持键盘导航、高色彩对比度模式、减少的动态效果等等。

验证 UI 辅助功能最准确的方法是在真实设备上手动测试。但是手动测试需要大量的工作,因此大多数团队使用像 Axe 这样的自动化工具作为第一道防线。

本文展示了如何使用 Storybook 运行自动化辅助功能测试。你将学习如何配置 Storybook 测试运行器以在所有组件上运行 Axe 并快照辅助功能树。

在编码时测试辅助功能

在编码时修复辅助功能问题比在应用程序部署后更容易。像 Axe 这样的自动化工具通过审核渲染的 DOM 来工作。这使开发人员能够在构建 UI 时捕获并解决缺陷。

Axe 基于 WCAG 规则和其他行业公认的最佳实践运行检查。使用 Axe 不会自动使你的 UI 具有辅助功能,但它可以平均发现 57% 的 WCAG 问题

Storybook 的 Accessibility 插件 在当前选定的 story 上运行 Axe,并在辅助功能面板中可视化测试结果。它甚至可以概述 DOM 节点,以帮助你一目了然地查明违规行为。

在处理组件时,你可以循环浏览其 stories 以验证其外观并发现辅助功能问题。

Storybook highlights the offending DOM nodes and gives you an audit report

有关使用和配置 A11y 插件的更多信息,请参阅设置指南

自动捕获辅助功能回归

对组件的更改可能会无意中引入新的辅助功能问题。要捕获此类回归,你需要在打开拉取请求之前测试所有 stories。

Accessibility 插件仅在你查看 story 时运行检查。我们希望通过 Storybook 测试运行器一次在所有 stories 上运行 Axe。它是一个独立的实用程序(由 JestPlaywright 提供支持),用于检查 stories 中的渲染错误。

让我们继续设置测试运行器并配置它以运行 Axe。我们将从安装测试运行器和相关软件包开始(注意,它需要 Storybook 6.4 或更高版本)。

npm i -D jest @storybook/test-runner axe-playwright

并安装 playwright 依赖项

npx playwright install --with-deps

然后,你可以使用 Storybook 测试运行器和 axe-playwright 将这些辅助功能测试集成到你的测试自动化管道中。

在你的 Storybook 目录中添加一个新的 配置文件,内容如下

// .storybook/test-runner.js
 
const { injectAxe, checkA11y } = require('axe-playwright');
 
module.exports = {
 async preRender(page, context) {
   await injectAxe(page);
 },
 async postRender(page, context) {
   await checkA11y(page, '#root', {
     detailedReport: true,
     detailedReportOptions: {
       html: true,
     },
   })
 },
};

preRenderpostRender 是方便的钩子,允许你配置测试运行器以执行其他任务。我们使用这些钩子将 Axe 注入到 story 中,然后在它渲染后,运行辅助功能测试。

你会注意到传递给 checkA11y 函数的几个选项。我们已将 Axe 设置为从 story 的根元素开始,然后遍历 DOM 树以检查问题。它还将根据遇到的问题生成详细的报告,并输出违反辅助功能规则的 HTML 元素列表。

要运行测试,请为测试运行器向你的 package.json 添加一个脚本。

{
  "scripts": {
    "test-storybook:ci": "yarn test-storybook --maxWorkers=2"
  }
}

然后在其中一个终端窗口中使用 npm run storybook 启动你的 Storybook,在另一个终端窗口中使用 npm run test-storybook 启动测试运行器。

test runner runs accessibility checks along with all your other component tests

导出测试结果

默认情况下,结果通过 CLI 报告。要改为导出它们,请切换到 getViolations 函数并使用 Node 的 fs API 将它们保存到 JSON 文件。

// .storybook/test-runner.js
 
const { injectAxe, getViolations } = require('axe-playwright');
const fs = require('fs');
 
module.exports = {
 setup() {
   fs.mkdir(
     process.cwd() + '/src/__accessibility__/',
     { recursive: true },
     (err) => {
       if (err) throw err;
     }
   );
 },
 async preRender(page, context) {
   await injectAxe(page);
 },
 async postRender(page, context) {
   const violations = await getViolations(page, '#root', {
     detailedReport: true,
   });
 
   // Do something with violations
   // For example, write them to a file
   await new Promise((resolve, reject) => {
     fs.writeFile(
       process.cwd() + `/src/__accessibility__/${context.id}.json`,
       JSON.stringify(violations, null, 2),
       (err) => {
         if (err) reject(err);
         resolve();
       }
     );
   });
 },
};

快照辅助功能树以检查页面结构

失明和视力障碍用户依赖屏幕阅读器等辅助技术来理解和与你的 UI 交互。浏览器将你的标记转换为称为辅助功能树的内部表示。它是使屏幕阅读器能够解析你的 UI 并将视觉界面转换为语音的机制。

快照辅助功能树可帮助你了解 UI 如何被这些辅助设备解析。你可以检查页面结构是否正确,以及内容是否以正确的顺序呈现。更重要的是,跟踪和比较这些快照,以便在你修改或更新 UI 时捕获回归。

// .storybook/test-runner.js

const { injectAxe, checkA11y } = require('axe-playwright');
 
module.exports = {
 async preRender(page, context) {
   await injectAxe(page);
 },
 async postRender(page, context) {
   await checkA11y(page, '#root', {
     detailedReport: true,
     detailedReportOptions: {
       html: true,
     },
   });
 
   const accessibilityTree = await page.accessibility.snapshot();
   expect(accessibilityTree).toMatchSnapshot();
 },
};

结论

美国 26% 的成年人 至少患有一种残疾。提高辅助功能可以对你的用户群产生重大影响。

自动化辅助功能测试充当 QA 的第一道防线,以捕获明显的辅助功能违规行为。虽然自动化不会自动使你的 UI 具有辅助功能,但它确实通过允许你在开发期间发现问题来缩短反馈循环。

Storybook Accessibility 插件审核你的 stories 并突出显示违规的 DOM 节点。准备好合并后,使用 Storybook 测试运行器对所有组件运行检查以捕获回归。

了解如何在 CI 中使用测试运行器,请参阅我们的入门指南

加入 Storybook 邮件列表

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

6,730位开发者以及更多

我们正在招聘!

加入 Storybook 和 Chromatic 背后的团队。构建被成千上万的开发者在生产中使用的工具。远程优先。

查看职位

热门文章

Storybook 6.5

使你更高效的新工作流程
loading
Michael Shilman

为什么大多数设计系统会崩溃

我们询问了 Brad Frost,设计系统在 2022 年是否仍然相关?
loading
Michael Chan

Storybook 性能:Vite vs Webpack

我们对两个构建器进行了基准测试,以查看哪个更快。
loading
Ian VanSchooten
加入社区
6,730位开发者以及更多
为什么为什么选择 Storybook组件驱动的 UI
文档指南教程更新日志遥测
社区插件参与进来博客
案例展示探索项目组件词汇表
开源软件
Storybook - Storybook 中文

特别感谢 Netlify CircleCI