© Denys Zelenchuk 2019
Denys ZelenchukAndroid Espresso Revealedhttps://doi.org/10.1007/978-1-4842-4315-2_7

7. Accessibility Testing

Denys Zelenchuk1 
(1)
Zürich, Switzerland
 

Most mobile applications are developed with established assumptions about the users or user types. In software testing, the term user personas reflects such user types, including their possible usage flows and how the application might help them in their daily activities. Despite the fact that user personas are created during the early stages of the software development lifecycle, they may not consider people with disabilities.

Around 300 million people around the world have a visual impairment and use mobile applications with the help of specific accessibility tools installed on their mobile devices.

Android Accessibility Tools

There are three tool types available on the Android platform for people with visual impairments:
  • TalkBack—The preinstalled screen reader application that allows users to interact with Android applications without visual access to the screen. Users with visual impairments may rely on TalkBack to use your app.

  • BrailleBack —An accessibility service that helps users with visual impairments use Braille devices. Working in combination with the TalkBack app, it provides a combined Braille and speech experience.

  • Voice Access —Lets users control their Android devices with voice commands. Voice Access is available on devices running Android 5.0 (API level 21) and higher.

As you can see, BrailleBack relies on TalkBack, which reads back each interactive element available on the active screen to the user. In order to make Android applications accessible to users with visual impairments, developers should follow accessibility guidelines. Among them:
  • Label UI elements —Many screen readers, such as TalkBack, rely on this service to properly explain the function of a particular control. For example, for UI objects such as ImageView and ImageButton objects, the android:contentDescription parameter is set to specify its purpose. For EditText objects, android:hint is used.

  • Group content —Just as the visual UI is grouped into understandable components like lists with list items, so the screen reader content should also be grouped in a logical way. Instead of being presented as separate elements, items should be read back as a single announcement—a TO-DO item with a title, a description, and a checkbox state.

  • Create an easy-to-follow navigation —Applications should support keyboards navigation and navigation gestures. Avoid having UI elements fade out or disappear after a certain amount of time.

  • Make touch targets large —By providing larger touch targets, you make it substantially easier for users to navigate your app. In general, according to the guidelines, the touchable area of focusable item should be a minimum of 48dpx48dp.

  • Provide adequate color contrast —People with poor vision or those who use devices with dimmed displays have difficulty reading information on the screen. By providing increased contrast ratios between the foreground and background colors in your app, you make it easier for users to navigate within and between screens.

Testing Application Accessibility

The Espresso testing framework supports writing automated accessibility tests that evaluate the accessibility of your application. In order to start writing accessibility tests, add the following dependencies to the build.gradle file.

Android Testing Support Library Accessibility Dependencies in the build.gradle File Inside the App Module.
androidTestImplementation "com.android.support.test.espresso:espresso-accessibility:3.0.2"
androidTestImplementation "com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:2.1"
AndroidX Test library Accessibility Dependencies in the build.gradle file Inside the App Module .
androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.1.0'
androidTestImplementation "com.google.android.apps.common.testing.accessibility.framework:accessibility-test-framework:2.1"
After adding these dependencies, you have to enable accessibility checks, as shown in this sample:
companion object {
    @BeforeClass
    @JvmStatic
    fun setAccessibilityPrefs() {
        AccessibilityChecks.enable()
    }
}

Note

AccessibilityChecks should be enabled only once per test class, otherwise, the test will fail. Therefore, the @BeforeClass annotation should be used with methods in which checks are enabled. In Kotlin, the method annotated with the @BeforeClass annotation should be declared in the class companion object.

With AccessibilityChecks.enable() set, checks are enabled each time the Espresso ViewAction is called on the UI element, including its descendants. Such approach limits accessibility testing to UI test coverage.

To cover more UI elements within the test run, set setRunChecksFromRootView(true), which enables you to validate the entire view hierarchy.

Companion Object in chapter7 . AccessibilityTest.kt Class .
    @BeforeClass
    @JvmStatic
    fun setAccessibilityPrefs() {
        AccessibilityChecks.enable().setRunChecksFromRootView(true)
    }

Unfortunately, it is not possible to set accessibility checks on each test method or test class, or to disable it after a test run.

There can be cases when an accessibility issue is known but has not been resolved. With the help of AccessibilityValidator implemented in com.google.android.apps.common.testing.accessibility.framework, you can suppress it:
@BeforeClass
@JvmStatic
fun setAccessibilityPrefs() {
    AccessibilityChecks.enable()
            .setRunChecksFromRootView(true)
            .setSuppressingResultMatcher(AccessibilityCheckResultUtils.matchesViews(
                    hasSibling(withId(R.id.menu_filter))))
}
In a similar way, you can suppress multiple accessibility issues with the help of the anyOf() matcher , as shown here:
@BeforeClass
@JvmStatic
fun setAccessibilityPrefs() {
    AccessibilityChecks.enable()
            .setRunChecksFromRootView(true)
            .setSuppressingResultMatcher(AccessibilityCheckResultUtils.matchesViews(anyOf(
                    hasSibling(withId(R.id.menu_filter)),
                    withChild(withChild(withId(android.support.design.R.id.snackbar_text))))))
}

By the way, you may notice accessibility issues with the native Android UI elements like snackbar. Suppressing them sometimes is not an easy task. In the previous code sample, the withChild() view matcher was used twice to locate the snackbar root layout and suppress the accessibility issue for it.

You can also keep tests running even with accessibility issues, by providing a false value to the setThrowExceptionForErrors() method :
@BeforeClass
@JvmStatic
fun setAccessibilityPrefs() {
    AccessibilityChecks.enable()
            .setRunChecksFromRootView(true)
            .setSuppressingResultMatcher(AccessibilityCheckResultUtils.matchesViews(anyOf(
                    hasSibling(withId(R.id.menu_filter)),
                    withChild(withChild(withId(android.support.design.R.id.snackbar_text))))))
            .setThrowExceptionForErrors(false)
}
In this case, all the issues will be redirected to the logcat log , where logs with I are informative and shown in black, W are warnings and are in blue, and E are errors and are in red. See Figure 7-1.
../images/469090_1_En_7_Chapter/469090_1_En_7_Fig1_HTML.jpg
Figure 7-1

Accessibility logcat logs when setThrowExceptionForErrors(false) is set

This is how the accessibility issue stacktrace looks like after a test fails:
com.google.android.apps.common.testing.accessibility.framework.integrations.AccessibilityViewCheckException: There was 1 accessibility error:
OverflowMenuButton{id=-1, desc=More options, visibility=VISIBLE, width=105, height=126, has-focus=false, has-focusable=false, has-window-focus=false, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=true, is-layout-requested=false, is-selected=false, layout-params=android.support.v7.widget.ActionMenuView$LayoutParams@48cbb74, tag=null, root-is-layout-requested=true, has-input-connection=false, x=127.0, y=10.0}: View falls below the minimum recommended size for touch targets. Minimum touch target width is 48dp. Actual width is 40dp.
at com.google.android.apps.common.testing.accessibility.framework.integrations.espresso.AccessibilityValidator.processResults(AccessibilityValidator.java:187)...

You may notice that the header parts in both cases are identical.

In addition to automated accessibility testing, Google developers also provide a possibility to test manually using the Accessibility Scanner application ( https://play.google.com/store/apps/details?id=com.google.android.apps.accessibility.auditor ).

This application allows you to check for accessibility issues types and better understand errors shown in your Espresso accessibility test reports or inside the logcat logs based on the visual representation.

Figure 7-2 shows the accessibility scanner setup process.
../images/469090_1_En_7_Chapter/469090_1_En_7_Fig2_HTML.jpg
Figure 7-2

Start using the Accessibility scanner flow

Figure 7-3 shows a couple of accessibility analysis examples with accessibility issues in the sample TO-DO application.
../images/469090_1_En_7_Chapter/469090_1_En_7_Fig3_HTML.jpg
Figure 7-3

Accessibility issues in the Create Task view

Exercise 19

Executing Accessibility Tests
  1. 1.

    Install the Accessibility Scanner application and enable accessibility checks. Launch the sample TO-DO application and perform the accessibility checks across the application. Observe the issue types.

     
  2. 2.

    Run tests from the AccessibilityTest.kt class with the AccessibilityChecks.enable() option only. Observe the test results.

     
  3. 3.

    Run tests from the AccessibilityTest.kt class with the setRunChecksFromRootView(true) option. Observe the test results.

     
  4. 4.

    Suppress some accessibility failures, as shown in the AccessibilityTest.kt class’s setAccessibilityPrefs() method, and run the tests again. Observe the test results.

     
  5. 5.

    Add the setThrowExceptionForErrors(false) parameter and run the tests. Observe the test results and device logcat logs.

     

Summary

Unfortunately, accessibility testing is frequently ignored, with the focus mostly on functional testing. It may be not clear from the first look, but good accessibility support is important too. Its main goal is to make applications accessible to people with visual impairments, but it also has nice side effects—it makes your applications more testable and helps you understand different application use cases. It maybe even result in your application getting a higher Google PlayStore rating, since Android-crawling algorithms may analyze the application from the accessibility side and give preference to those with proper accessibility support.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.141.30.162