Perform accessibility audits for your app
Accessibility & Inclusion 进阶 20m

为你的应用执行无障碍审计

Perform accessibility audits for your app

2023年6月5日

在 Apple 官方观看视频

一句话判断

Xcode 15 让无障碍审计变成了自动化测试——一行代码 performAccessibilityAudit() 就能在 UI 测试中发现元素描述缺失、对比度不足等问题,不再需要手动逐个检查。

这场 Session 讲了什么

Session 介绍了 Xcode 15 中无障碍审计的自动化能力,以及如何正确设置无障碍属性让审计和 UI 测试同时受益。

自动化无障碍审计。以前你需要在 Accessibility Inspector 中手动运行审计,现在可以在 UI 测试中调用 performAccessibilityAudit()。它会检查当前视图的常见无障碍问题:元素描述缺失、标签不可读、对比度不足等。发现问题时测试自动失败,问题报告直接内联在 Xcode 源码编辑器中。

问题的诊断与修复。Session 用一个示例 App 展示了完整流程:审计发现两个问题——图片视图没有描述、文本视图的 accessibility label 使用了非人类可读的字符串。修复方式是把 accessibilityLabel 改为 accessibilityIdentifier(后者只影响 UI 测试定位,不影响 VoiceOver 体验),并对纯装饰性图片从 accessibilityElements 中排除。

过滤误报performAccessibilityAudit 支持两个可选参数:第一个指定要审计的类别(如动态字体、对比度),第二个是一个闭包,让你决定哪些问题要报告、哪些要忽略(比如已知的误报)。

UI 测试与无障碍的协同。Session 强调了一个关键观点:如果你的 UI 测试能找到元素,辅助技术也能找到——因为 XCTest 依赖无障碍属性来定位元素。这意味着写好 UI 测试本身就是在做好无障碍的基础工作。

值得深挖的点

accessibilityLabel vs accessibilityIdentifier:这是一个常见混淆。Label 会被 VoiceOver 读出来,应该是人类可读的;Identifier 只用于 UI 测试定位,VoiceOver 不会使用。很多开发者把自动化标识符放在 label 里,导致 VoiceOver 读出 “QUOTE_TEXTVIEW” 这样的奇怪内容。

装饰性元素的处理:背景图片、分隔线等纯装饰元素不应该被 VoiceOver 关注。通过 accessibilityElements 属性只暴露有意义的内容元素,让 VoiceOver 用户更高效地导航。

审计与测试的融合:把无障碍审计集成到 CI/CD 中意味着每次代码变更都会检查无障碍回归。这比”上线前做一次无障碍检查”的方式可靠得多。

代码片段

在 UI 测试中执行无障碍审计:

func testAccessibilityQuoteTabView() throws {
    let app = XCUIApplication()
    app.launch()

    // 导航到目标页面
    app.tabBars.buttons["Quote"].tap()

    // 允许报告所有问题(不因第一个失败而停止)
    continueAfterFailure = true

    // 执行无障碍审计——一行代码搞定
    try app.performAccessibilityAudit()
}

带过滤器的无障碍审计:

// 只审计特定类别,并过滤掉已知误报
try app.performAccessibilityAudit(
    categories: [.dynamicType, .contrast]  // 只检查动态字体和对比度
) { issue in
    // 返回 false 表示忽略这个问题
    if issue.description.contains("已知的低对比度区域") {
        return false  // 忽略这个误报
    }
    return true  // 报告其他问题
}

最佳实践

  • performAccessibilityAudit() 加入每个 UI 测试用例,CI 中自动检测无障碍回归
  • accessibilityIdentifier 而非 accessibilityLabel 来定位 UI 测试元素
  • 纯装饰性元素不要设置无障碍属性,通过 accessibilityElements 控制暴露范围
  • 审计发现问题时,先确认是否为误报再决定是否过滤
  • 设置 continueAfterFailure = true 让审计报告所有问题而非停在第一个

还有什么值得关注

  • 无障碍审计支持的所有类别(动态字体、对比度、元素描述等)
  • Accessibility Inspector 的独立使用方式和与自动化审计的互补关系
  • SwiftUI 视图的无障碍属性设置最佳实践
  • VoiceOver 的测试方法——模拟器 + 命令行的辅助测试流程
WWDC 2023