测试应用的无障碍功能 (Views)

概念和 Jetpack Compose 实现

通过测试无障碍功能,您可以从用户的角度体验您的应用,并发现原本可能忽略的易用性问题。无障碍功能测试可以挖掘出改进机会,使您的应用变得功能更强大且更多样,造福于所有用户,包括残障用户。

本文档介绍了以下方法:

  • 使用分析工具进行测试:使用各种工具发现改进应用无障碍功能的机会 。
  • 自动化测试:在 Espresso 和 Robolectric 中开启无障碍功能测试。

使用分析工具进行测试

分析工具可以发现手动测试可能会错失的无障碍功能改进机会。

无障碍功能扫描仪

无障碍功能扫描仪应用会扫描您的屏幕,并提出关于如何改进应用无障碍功能的建议。无障碍功能扫描仪使用无障碍功能测试框架,并在查看内容标签、可点击项、对比度等内容后提供具体建议。

Android Studio 中集成了 Android 无障碍功能测试框架,有助于查找布局中的无障碍功能问题。如需启动面板,请点击布局编辑器中的错误报告按钮 ![/static/studio/images/releases/atf-scanner.gif]。

无障碍功能扫描仪演示 图 1. 无障碍功能扫描仪演示

如需了解详情,请参阅以下资源:

UI Automator 查看器

uiautomatorviewer 工具提供了一个方便的 GUI,可扫描和分析 Android 设备上当前显示的界面组件。您可以使用 UI Automator 检查布局层次结构,并查看在设备前台显示的界面组件的属性。利用此信息,您可以创建更精细的测试。例如,通过创建与特定可见属性匹配的界面选择器来做到这一点。该工具位于 Android SDK 的 tools 目录中。

在无障碍功能测试中,此工具对于调试使用其他测试方法发现的问题很有用。例如,如果手动测试揭示了某个视图应包含却未包含可朗读的文本,或者某个视图不应获得却获得了焦点,您可以使用该工具帮助找出问题根源。

如需详细了解 UI Automator 查看器,请参阅使用 UI Automator 编写自动化测试

lint

Android Studio 会显示有关各种无障碍功能问题的 lint 警告,并提供指向源代码中相关位置的链接。在以下示例中,一张图片缺少 contentDescription 属性。缺少内容说明会导致生成以下消息:

[Accessibility] Missing 'contentDescription' attribute on image

图 2 举例说明了此消息在 Android Studio 中是什么样子的:

显示 Android Studio 报告某些图片缺少内容说明的图片。
图 2.Android Studio 中显示缺少 contentDescription 属性的消息。

自动测试

Android 平台支持多个测试框架(例如 Espresso),每个框架都允许您创建并运行自动化测试,以评估应用的无障碍功能。

Espresso

Espresso 是一个 Android 测试库,旨在打造简单快捷的界面测试体验。它可让您与应用中的被测界面组件互动,并断言会发生某些行为或满足特定条件。

如需通过视频简要了解如何使用 Espresso 进行无障碍功能测试,请观看以下视频(从 31 分 54 秒到 34 分 19 秒):包容性设计和测试:让您的应用使用起来更没有障碍 - 2016 年 Google I/O 大会

本部分介绍如何使用 Espresso 运行无障碍功能检查。

启用检查

您可以使用 AccessibilityChecks 类启用和配置无障碍功能测试:

Kotlin

import androidx.test.espresso.accessibility.AccessibilityChecks

@RunWith(AndroidJUnit4::class)
@LargeTest
class MyWelcomeWorkflowIntegrationTest {
    init {
        AccessibilityChecks.enable()
    }
}

Java

import androidx.test.espresso.accessibility.AccessibilityChecks;

@RunWith(AndroidJUnit4.class)
@LargeTest
public class MyWelcomeWorkflowIntegrationTest {
    @BeforeClass
    public void enableAccessibilityChecks() {
        AccessibilityChecks.enable();
    }
}

默认情况下,当您执行 ViewActions 中定义的任何视图操作时,系统都会运行检查。每次检查都包括执行操作所在的视图以及所有后代视图。您可以在每次检查期间评估屏幕的整个视图层次结构,方法是将 true 传入 setRunChecksFromRootView(),如以下代码段所示:

Kotlin

AccessibilityChecks.enable().setRunChecksFromRootView(true)

Java

AccessibilityChecks.enable().setRunChecksFromRootView(true);

抑制结果的子集

Espresso 针对应用运行无障碍功能检查后,您可能会发现一些有助于改进应用的无障碍功能,但无法马上进行处理的结果。为了防止 Espresso 测试因这些结果而不断失败,您可以暂时忽略它们。无障碍功能测试框架 (ATF) 使用 setSuppressingResultMatcher() 方法提供此功能,借此指示 Espresso 抑制满足给定匹配器表达式的所有结果。

如果您对应用所做的更改可以改进无障碍功能的一个方面,让 Espresso 尽可能多地显示无障碍功能其他方面的结果会有好处。因此,最好仅抑制已知的具体改进机会。

如果您暂时抑制无障碍功能测试的某些结果,打算以后再处理,切勿意外抑制类似的结果。因此,请使用作用域较小的匹配器。为此,选择的匹配器应确保只有在给定的结果满足以下每项无障碍功能检查的条件时,Espresso 才会抑制该结果:

  1. 某种类型的无障碍功能检查,如用于检查触摸目标大小的无障碍功能检查。
  2. 用于评估特定界面元素(如按钮)的无障碍功能检查。

ATF 定义了多个匹配器,以帮助您定义要在 Espresso 测试中显示的结果。以下示例会抑制与单个 TextView 元素的色彩对比度相关的检查结果。元素的 ID 为 countTV

Kotlin

AccessibilityChecks.enable().apply {
        setSuppressingResultMatcher(
                allOf(
                    matchesCheck(TextContrastCheck::class.java),
                    matchesViews(withId(R.id.countTV))
                )
        )
}

Java

AccessibilityValidator myChecksValidator =
    AccessibilityChecks.enable()
        .setSuppressingResultMatcher(
            allOf(
                matchesCheck(TextContrastCheck.class),
                matchesViews(withId(R.id.countTV))));