- 测试
【免费下载链接】axe-core
Accessibility engine for automated Web UI testing
导读
本指南讲解 axe-core(面向自动化 Web UI 测试的可访问性引擎)中新规则的提案流程:在动手编写任何规则代码之前,你必须先在 GitHub Issue 中提交一份结构化的规则提案,用于记录规则意图、征询开发团队反馈,并为未来维护留下文档依据。读完本文,你将掌握 axe-core 规则提案的标准格式(Intro / Rule help / Tags / Selector / Checks)、设计最佳实践、可直接复制的 Issue 模板,以及如何将提案格式与 W3C ACT Rules 标准相互映射。
为什么先提案、后编码
在 axe-core 中,规则(rule)是定义一次测试的 JSON 对象:先通过选择器找到待测元素,再运行若干检查(check)判断这些元素是否通过。写规则的代码并不难,难的是写出一条不会误报(false positive)的规则。
doc/rule-proposal.md明确指出:开始编码之前,你必须创建一条 GitHub Issue 来记录想要创建的规则。原因有二:
- 误报难以避免。可访问性测试的公认难题是边界情况(edge case)极多,一条好的规则必须零误报,而设计时几乎不可能一次性穷举所有边界。
- 解释必须统一。不同的测试者对无障碍准则的理解并不一致。所有规则必须与 Deque Systems(axe-core 的开发者)对准则的解释保持一致,不能各行其是。
此外,Issue 本身也会成为该规则未来的文档——团队可以在编码前对规则设计给出反馈,后人则可以借助 Issue 理解规则为何如此定义。这就是提案先行(proposal-first)工作流的核心价值。
在动手写规则之前,还建议先阅读 Developing Axe-core Rules,了解规则的 JSON 结构、selector/matches/all/any/none等机制;阅读 principles for deciding on rules 理解规则取舍的原则。
规则提案的 Issue 格式
所有提案规则的 GitHub Issue 必须打上rule标签,并使用下面的固定格式。
Intro
用一句话描述这条规则做什么。
示例:"Ensure ARIA attributes are allowed for an element's role"(确保元素的 ARIA 属性在其角色允许范围内)
Rule help
用一句话描述如何解决该问题(这是用户在违规报告中看到的帮助文案)。
示例:"Elements must only use allowed ARIA attributes"(元素只能使用允许的 ARIA 属性)
对照源码,这一文案正是规则元数据中的help字段。以 lib/rules/aria-allowed-attr.json 为例:
{ "metadata": { "description": "Ensure an element's role supports its ARIA attributes", "help": "Elements must only use supported ARIA attributes" } }Tags
标明规则应使用的标签(tags),用于规则分组与过滤。标签体系详见 how we assign tags documentation。
示例:
wcag2a, wcag211, cat.keyboard
真实规则中的 tags 会更丰富。仍以 aria-allowed-attr 为例,它同时挂了规范标签(wcag2a、wcag412)、分类标签(cat.aria)以及区域性标准标签(EN-301-549、RGAAv4 等):
"tags": [ "cat.aria", "wcag2a", "wcag412", "EN-301-549", "EN-9.4.1.2", "RGAAv4", "RGAA-7.1.1" ]Selector
尽可能使用 CSS 选择器描述规则选取的元素;无法用选择器表达时,用一句通俗语言描述。
示例 1:
input[type=checkbox][name]示例 2:Select each node that has an attribute starting with
aria-.
从源码结构看,规则文件中的selector字段即为最终实现时的 CSS 选择器;当选择器不足以精确定位时,还可以补充matches函数做二次过滤(见 Developing Axe-core Rules)。
Checks
将每个检查(check)作为checks小节下的子标题,标题中给出检查名称,并注明检查类型是any、all还是none。
用通俗语言、短句描述什么条件下检查返回 false、true 或 undefined。保持步骤简短,不必写出全部逻辑,给出高层视图即可。
示例 1(any 型检查):
###aria/allow-attr (any)
- 查找元素的 role
- 查找该 role 允许的 aria 属性列表
- 若元素含有不在列表中的 aria 属性,返回 false
- 否则返回 true
示例 2(none 型检查):
###keyboard/focusable-no-name (none)
- 若元素不在焦点顺序中,返回 false
- 若元素有可访问名称,返回 false
- 否则返回 true
这里可以对比真实实现。aria-allowed-attr 规则包含三个all检查和一个none检查(lib/rules/aria-allowed-attr.json):
"all": [ "aria-allowed-attr", "aria-allowed-attr-elm", "aria-no-deprecated-attr" ], "any": [], "none": ["aria-unsupported-attr"]其核心检查 lib/checks/aria/aria-allowed-attr-evaluate.js 的实现正是提案示例的展开:
export default function ariaAllowedAttrEvaluate(node, options, virtualNode) { const invalid = []; const role = getRole(virtualNode); let allowed = allowedAttr(role); for (const attrName of virtualNode.attrNames) { if ( validateAttr(attrName) && !allowed.includes(attrName) && !ignoredAttrs(attrName, virtualNode.attr(attrName), virtualNode) ) { invalid.push(attrName); } } if (!invalid.length) { return true; } this.data( invalid.map(attrName => attrName + '="' + virtualNode.attr(attrName) + '"') ); ... }可见"查找 role → 对比允许属性列表 → 返回 true/false"正是提案文档的直译。值得注意的还有两个实现层面的边界处理(ignoredAttrs):aria-required="false"与带contenteditable时的aria-multiline="false"会被视为允许——这类"常识上的例外"正是提案阶段需要反复推敲的边界情况,也解释了为什么必须先把规则讲清楚再编码。
规则设计最佳实践
规则设计方面,doc/rule-proposal.md 给出三条硬性建议:
- 规则只应有一个
none检查,这样错误信息才足够具体——多个none检查失败时无法确定哪一条才是根因。 - 规则不应混用
any与none,应当拆分成独立规则。混用会让"至少一个通过"与"全部必须失败"的语义纠缠在一起,难以推理与维护。 - 每个检查只测试一个具体场景(要么是一个通过技术,要么是一个单一失败场景),保持检查的单一职责。
这三条原则在真实规则中都能找到印证:例如上面的 aria-allowed-attr 只用了一个none检查(aria-unsupported-attr),并把"通过"侧的多个条件拆成三个all检查,每个检查只负责一类判定。
可直接复用的 Issue 模板
创建提案 Issue 时直接使用下面的模板(来自原文档):
# {{ Rule name }} {{ Rule description }} {{ Rule help }} **Tags:** {{ tag, tag, tag }} ## Selector {{ selector }} ## Checks ### {{ Check name 1 }} ( any / all / none ) 1. ### {{ Check name 2, optional }} ( any / all / none ) 1.模板中的{{ }}占位符对应上一节的六个要素:规则名、规则描述(Intro)、规则帮助(Rule help)、标签(Tags)、选择器(Selector)、检查(Checks)。其中 Checks 可写一个或多个,每个检查都要标注any/all/none类型并列出判定步骤。
从提案到可运行规则
提案获得认可后,下一步就是编写规则本体。axe-core 为规则生成提供了脚手架脚本:在项目根目录执行
pnpm install pnpm run rule-gen即可启动规则生成 CLI(该脚本定义在 package.json 的rule-gen脚本中,实现位于 build/rule-generator.mjs)。脚本会先确认构建产物存在(缺失时自动触发pnpm run build),然后通过交互式问答收集规则信息,并生成规则文件及配套文件。注意该 CLI 在 CI 环境会被拒绝运行(if (CI) throw new Error(...)),因此只能在本地开发环境使用。
生成后的规则 JSON 放在 lib/rules,对应的检查实现放在 lib/checks 下各分类目录(如aria、keyboard、color)。每条规则还需要配套集成测试:以 aria-allowed-attr 为例,测试位于 test/integration/rules/aria-allowed-attr,包含passes.json、failures.json、incomplete.json三份用例清单,分别声明应通过、应失败、应判为需人工复查(incomplete)的元素;对应的 HTML 测试页面在 integration/full 目录中按规则组织。
提案中"检查返回 true/false/undefined"的三态语义也贯穿到测试设计:incomplete(未完成)结果是 axe-core 无法得出明确通过/失败结论时给出的结果,把人工复查的机会留给用户。例如 color-contrast 检查在背景色无法确定时返回 undefined,并附带missingData说明原因(详见 Developing Axe-core Rules 中对 incomplete 消息格式的说明)。
与 W3C ACT Rules 标准的关系
axe-core 的提案格式并非凭空设计:Deque Systems 是标准化可访问性一致性测试规则开发的主导组织之一,上述格式是 Accessibility Conformance Testing Rules Format(ACT Rules) 给出了两条转换路径:
方法一:创建单一规则。适用于检查数量较少的规则——补上测试输入类型(rendered page)、assumptions、outcomes、Validation Tests等 ACT 章节,把检查返回值从 true/false/undefined 改为 pass/fail/cantTell,并按"any 检查只在最后一步返回 fail、all/none 检查只在最后一步返回 pass"的规则改写控制流,最后把checks改名为steps、把tags替换为Accessibility Requirements。
方法二:创建规则组。适用于带any检查的大型规则——把每个检查拆成一条独立规则,原规则退化为规则组;各新规则沿用原 selector、补全 ACT 章节,并用原 axe-core 规则 ID 作为组名。
从仓库中的实际落地看,axe-core 通过规则 JSON 中的actIds字段(如 aria-allowed-attr 的"actIds": ["5c01ea"])关联对应的 ACT 规则 ID,对应测试文件为 test/act-rules/aria-state-or-property-permitted-5c01ea.spec.js。这意味着按本文模板撰写的提案,最终可以顺畅地演进为符合 W3C 标准的正式规则。
小结
一条合格的 axe-core 规则,始于一份结构化、可评审、可追溯的提案。核心要点可归纳为:
- 提案先行:编码前在 GitHub Issue 中打上
rule标签,按固定格式说明规则做什么、如何帮助用户、使用哪些标签、选择哪些元素、每个检查的判定逻辑。 - 格式六要素:Intro、Rule help、Tags、Selector、Checks 缺一不可;Checks 中的每个检查标注
any/all/none类型。 - 设计三原则:单一
none检查、不混用any与none、检查职责单一,是降低误报、保证错误信息可读性的关键。 - 模板直达实现:提案通过后可用
pnpm run rule-gen生成规则骨架,再按 Developing Axe-core Rules 完善实现与测试。 - 与标准对齐:提案格式改编自 W3C ACT Rules 格式,可依据 act-rules-format.md 的两种方法转换为符合国际标准的规则。
- 测试
【免费下载链接】axe-core
Accessibility engine for automated Web UI testing
相关推荐
如何快速实现Immich地理编码汉化:面向中文用户的完整指南
如何快速实现Immich地理编码汉化:面向中文用户的完整指南 你是否在使用Immich管理照片时,被满屏的英文位置信息困扰?immich geodata cn项
数据集GISOpenMetadata数据血缘追踪:企业级数据治理的完整解决方案
OpenMetadata数据血缘追踪:企业级数据治理的完整解决方案 在数据驱动的决策时代,企业面临的最大挑战已经从数据收集转向了 数据理解 。当数据异常发生时,
数据目录数据血缘数据治理后端MCP 服务Axe-core 核心功能解析:10个必知的无障碍测试规则
Axe core 核心功能解析:10个必知的无障碍测试规则 Axe core 是业界领先的 Web无障碍测试引擎 ,专为自动化UI测试设计。这个强大的开源工具能
测试
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考