Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introducing Android Accessibility Test with Accessibility Testing Framework

itome
June 28, 2019

Introducing Android Accessibility Test with Accessibility Testing Framework

itome

June 28, 2019
Tweet

More Decks by itome

Other Decks in Technology

Transcript

  1. Accessibility Test Framework
    で始める⾃動アクセシビリティテスト
    shibuya.apk #

    View Slide

  2. ⾃⼰紹介
    https://twitter.com/itometeam
    https://github.com/itome
    https://medium.com/@itometeam
    . min
    塚本武志
    CyberAgent CATS

    View Slide

  3. アプリのアクセシビリティには
    どんなものがあるの?
    min

    View Slide

  4. アプリのアクセシビリティにはどんなものがあるの
    ‧Talkbackを使った⾳声によるガイド
    3min
    過去のスライド https://speakerdeck.com/itome/android-accessibility-suite
    - Android Accessibility Suiteに含まれるTalkBack機能を使った⾳声ガイド
    - TextViewなどは⾃動でコンテンツが読み上げられる
    - ImageViewやCanvasに直接描画されたテキストは開発者がTalkback内容を
     指定する必要がある

    View Slide

  5. アプリのアクセシビリティにはどんなものがあるの
    ‧⽂字⾊と背景⾊のコントラスト
    3min
    - ⽂字⾊と背景⾊のコントラストが低いと、⽂字の視認性が悪くなる
    - ⾊覚障害のユーザーだけでなく、⽇光の下でのアプリの使いやすさ
    にも影響する
    - マテリアルデザインガイドラインでは⼩さめのテキストでは4.5:1
    以上、⼤きめのテキストでも3:1以上のコントラストが推奨されて
    いる
    参照リンク https://material.io/design/usability/accessibility.html#color-contrast

    View Slide

  6. アプリのアクセシビリティにはどんなものがあるの
    ‧⽂字⾊と背景⾊のコントラスト
    3min
    - ⽂字⾊と背景⾊のコントラストが低いと、⽂字の視認性が悪くなる
    - ⾊覚障害のユーザーだけでなく、⽇光の下でのアプリの使いやすさ
    にも影響する
    - マテリアルデザインガイドラインでは⼩さめのテキストでは4.5:1
    以上、⼤きめのテキストでも3:1以上のコントラストが推奨されて
    いる
    参照リンク https://material.io/design/usability/accessibility.html#color-contrast

    View Slide

  7. アプリのアクセシビリティにはどんなものがあるの
    ‧⽂字サイズ
    3min
    - ⽂字サイズが⼩さいと、視認性が悪くなる
    - タイトルや説明⽂など、テキストのタイプによって推奨の⽂字サイズはさまざま
    - Androidでは、どんなタイプのテキストであっても12sp以上の⽂字サイズを指定することが推奨されている

    View Slide

  8. アプリのアクセシビリティにはどんなものがあるの
    ‧⽂字サイズ
    3min
    - ⽂字サイズが⼩さいと、視認性が悪くなる
    - タイトルや説明⽂など、テキストのタイプによって推奨の⽂字サイ
    ズはさまざま
    - Androidでは、どんなタイプのテキストであっても12sp以上の⽂字
    サイズを指定することが推奨されている

    View Slide

  9. アプリのアクセシビリティにはどんなものがあるの
    ‧ボタンのサイズ
    3min
    - マテリアルデザインガイドラインでは
    48dp x dp以上が推奨されている
    - ⼩さめのアイコンなど、それ⾃体で推奨サイズに届か
    ないボタンは、paddingでタップ可能領域を広げる
    参照リンク https://material.io/design/usability/accessibility.html#layout-typography

    View Slide

  10. アプリのアクセシビリティにはどんなものがあるの
    ‧その他
    3min
    - ボタンのタッチ領域が重ならないようにする
    - TextViewに埋め込まれたURLにTalkbackでもアクセスできるようにする
    - 冗⻑なcontentDescriptionを避ける(ボタンに対して「〜のボタン」と
    読み上げさせるなど)
    - etc

    View Slide

  11. アプリのアクセシビリティにはどんなものがあるの
    ‧その他
    3min
    - ボタンのタッチ領域が重ならないようにする
    - TextViewに埋め込まれたURLにTalkbackでもアクセスできるようにする
    - 冗⻑なcontentDescriptionを避ける(ボタンに対して「〜のボタン」と
    読み上げさせるなど)
    - etc

    View Slide

  12. アプリのアクセシビリティにはどんなものがあるの
    ‧その他
    3min
    - ボタンのタッチ領域が重ならないようにする
    - TextViewに埋め込まれたURLにTalkbackでもアクセスできるようにする
    - 冗⻑なcontentDescriptionを避ける(ボタンに対して「〜のボタン」と
    読み上げさせるなど)
    - etc

    View Slide

  13. アプリのアクセシビリティにはどんなものがあるの
    3min
    これらを⼈⼒で全てチェックするのは⼤変

    View Slide

  14. min
    Accessibility Testing Framework
    の導⼊

    View Slide

  15. Accessibility Testing Frameworkの導⼊
    5min
    ‧Accessibility TestingFramework for Androidとは 
    https://github.com/google/Accessibility-Test-Framework-for-Android

    View Slide

  16. Accessibility Testing Frameworkの導⼊
    5min
    ‧Accessibility TestingFramework for Androidとは 
    - 名前の通り、Androidアプリのアクセシビリティを⾃動でテストする
    ライブラリ
    - Viewの階層を分析して、アクセシブルでない要素があると教えてくれる
    - EspressoとRobolectricと連携する機能がある

    View Slide

  17. Accessibility Testing Frameworkの導⼊
    5min
    ‧導⼊⽅法
    dependencies {
    testImplementation "androidx.test.espresso:espresso-accessibility:$espressoVersion"
    }
    依存ライブラリにespress-accessibilityを追加する

    View Slide

  18. Accessibility Testing Frameworkの導⼊
    5min
    ‧導⼊⽅法
    import androidx.test.espresso.contrib.AccessibilityChecks
    @RunWith(AndroidJUnit4::class)
    @LargeTest
    class AccessibilityChecksIntegrationTest {
    companion object {
    @BeforeClass @JvmStatic
    fun enableAccessibilityChecks() {
    AccessibilityChecks.enable()
    }
    }
    }
    UIのテストクラスで、AccessibilityChecksを有効化する

    View Slide

  19. Accessibility Testing Frameworkの導⼊
    5min
    ‧導⼊⽅法
    何らかのViewActionを実⾏すると、⾃動的にAccessibilityCheckが⾛る
    @Test
    fun testButtonAccessibility() {
    onView(withId(R.id.button)).perform(click())
    }

    View Slide

  20. Accessibility Testing Frameworkの導⼊
    5min
    ‧テストできる項⽬

    View Slide

  21. Accessibility Testing Frameworkの導⼊
    5min
    ‧テストできる項⽬
    ClickableViewSpanCheck
    - URLSpan(テキストに含まれるリンク)に関するチェック
    - URLが絶対パスになっているか、ClickableSpanの中で使われて
    いるかをチェックしてくれる
    DuplicateClickableBoundsViewCheck
    - ボタンのタッチ領域が排他的になっているか(重なっていないか)
    をチェックしてくれる

    View Slide

  22. Accessibility Testing Frameworkの導⼊
    5min
    ‧テストできる項⽬
    DuplicateSpeakableTextViewHierachyCheck
    - TalkBackの読み上げが同じになっているViewがないかをチェック
    してくれる
    EditableContentDescriptionViewCheck
    - 編集可能なTextViewにContentDescriptionが付いていないかチェック
    してくれる
     (編集可能なTextViewのTalkbackは android:hint で提供されるため)

    View Slide

  23. Accessibility Testing Frameworkの導⼊
    5min
    ‧テストできる項⽬
    RedundantContentDescriptionViewCheck
    - 冗⻑な読み上げ⽂(ボタンに対して「〜のボタン」と読み上げるな
    ど)になっていないかをチェックしてくれる。
    SpeakableTextPresentViewCheck
    - 読み上げ可能なViewにきちんと読み上げ⽂がついているかをチェック
    してくれる
    - 英語のみ

    View Slide

  24. Accessibility Testing Frameworkの導⼊
    5min
    ‧テストできる項⽬
    TextContrastViewCheck
    - テキストと背景⾊のコントラストが、ガイドラインを満たしている
    かをチェックしてくれる
    TouchTargetSizeViewCheck
    - ボタンのタッチ領域が、ガイドラインを満たしているかをチェックして
    くれる

    View Slide

  25. min 実際にやってみる

    View Slide

  26. 実際にやってみる
    4min
    ‧今回テストするサンプルアプリ

    View Slide

  27. 実際にやってみる
    4min
    ‧テストクラス
    @RunWith(AndroidJUnit4::class)
    @LargeTest
    class MainActivityTest {
    companion object {
    @BeforeClass
    @JvmStatic
    fun enableAccessibilityChecks() {
    AccessibilityChecks.enable()
    .setRunChecksFromRootView(true)
    }
    }
    @Test
    fun testAccessibility() {
    ActivityScenario.launch(MainActivity::class.java).onActivity {
    onView(withId(R.id.button_small)).perform(click())
    }
    }
    }

    View Slide

  28. 実際にやってみる
    4min
    ‧テストクラスを⾛らせるとエラーが発⽣
    java.lang.NoSuchMethodError:
    com.google.android.apps.common.testing.accessibility.framework.integrations.espresso.AccessibilityValidato
    r.checkAndReturnResults(Landroid/view/View;)Lcom/google/common/collect/ImmutableList;
    at androidx.test.espresso.accessibility.AccessibilityChecks$2.check(AccessibilityChecks.java:65)
    at androidx.test.espresso.action.ViewActions$1.perform(ViewActions.java:130)
    at androidx.test.espresso.ViewInteraction$SingleExecutionViewAction.perform(ViewInteraction.java:366)
    at androidx.test.espresso.ViewInteraction.doPerform(ViewInteraction.java:255)
    at androidx.test.espresso.ViewInteraction.access$100(ViewInteraction.java:65)
    ライブラリの中で使われているjava.util.ListがなぜかGuavaのListとして扱われている
    → 解決できず(泣)

    View Slide

  29. 実際にやってみる
    4min
    ‧解決⽅法(あくまでワークアラウンド)
    Accessibility Testing FrameworkのEspresso連携を諦める
    Accessibility Testing Frameworkを直接使って、Viewの階層をテスト

    View Slide

  30. 実際にやってみる
    4min
    ‧解決⽅法(あくまでワークアラウンド)
    object AccessibilityChecker {
    fun check(root: View?, ignore: Matcher? = null) {
    if (root == null) throw NullPointerException()
    val validator = AccessibilityValidator()
    .setResultDescriptor(object :
    AccessibilityCheckResult.AccessibilityCheckResultDescriptor() {
    override fun describeView(view: View?): String {
    return HumanReadables.describe(view)
    }
    })
    .setSuppressingResultMatcher(ignore)
    val originalPolicy = StrictMode.allowThreadDiskWrites()
    try {
    validator.checkAndReturnResults(root)
    } finally {
    StrictMode.setThreadPolicy(originalPolicy)
    }
    }
    }

    View Slide

  31. 実際にやってみる
    4min
    ‧解決⽅法(あくまでワークアラウンド)
    @RunWith(AndroidJUnit4::class)
    @LargeTest
    class MainActivityTest {
    @Test
    fun testAccessibility() {
    ActivityScenario.launch(MainActivity::class.java).onActivity { activity ->
    AccessibilityChecker.check(activity.findViewById(android.R.id.content))
    }
    }
    }

    View Slide

  32. 実際にやってみる
    4min
    ‧テスト結果

    View Slide

  33. 実際にやってみる
    4min
    ‧テスト結果
    com.google.android.apps.common.testing.accessibility.framework.integrations.AccessibilityViewCheckExcept
    ion: There was 1 accessibility error:
    AppCompatTextView{
    id=2131165219,
    res-name=button_small,
    visibility=VISIBLE,
    width=27,
    height=32,
    has-focus=true,
    has-focusable=true,
    has-window-focus=true,
    is-clickable=true,
    is-enabled=true,
    is-focused=true,
    is-focusable=true,
    ……
    input-type=0,
    ime-target=false,
    has-links=false
    }:
    View falls below the minimum recommended size for touch targets. Minimum touch target size is 48x48dp.
    Actual size is 27x32dp.

    View Slide

  34. 実際にやってみる
    4min
    ‧テスト結果
    com.google.android.apps.common.testing.accessibility.framework.integrations.AccessibilityViewCheckExcept
    ion: There was 1 accessibility error:
    AppCompatTextView{
    id=2131165219,
    res-name=button_small,
    visibility=VISIBLE,
    width=27,
    height=32,
    has-focus=true,
    has-focusable=true,
    has-window-focus=true,
    is-clickable=true,
    is-enabled=true,
    is-focused=true,
    is-focusable=true,
    ……
    input-type=0,
    ime-target=false,
    has-links=false
    }:
    View falls below the minimum recommended size for touch targets. Minimum touch target size is 48x48dp.
    Actual size is 27x32dp.

    View Slide

  35. 実際にやってみる
    4min
    ‧テスト結果をもとに修正

    View Slide

  36. 実際にやってみる
    4min
    ‧テスト結果をもとに修正

    View Slide

  37. 実際にやってみる
    4min
    ‧テスト結果をもとに修正

    View Slide

  38. まとめ
    min

    View Slide

  39. まとめ
    2min
    ‧Accessibility Testing Frameworkを使うことで、アクセシビリティ
    に対応するコストが減らせそう
    ‧ドキュメントが少ないので、バグにハマると解決に時間がかかる
    ‧もちろん⾃動テストだけで⼗分なわけではないので、実際に⾃分で
    使ってみたり、ユーザーテストをしたりすることも⼤事

    View Slide

  40. ありがとうございました
    https://twitter.com/itometeam
    https://github.com/itome
    https://medium.com/@itometeam
    塚本 武志

    View Slide