Espresso & Accessibility
Included with Espresso is the AccessibilityChecks
class. This class uses the Accessibility Test Framework that is used throughout all of Android products.
Setup
Add the following lines to your build.gradle
dependencies in the Counter app project.
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
androidTestImplementation 'androidx.test.espresso:espresso-accessibility:3.5.0-beta01'
The app to test
The mobile app tested here, is a standard test counter app.
Test script
Instead of scanning an entire view, the tool will run a check when any action defined in ViewActions is called.
You can enable the check to scan the entire view and not just the item that had the action as well by adding setRunChecksFromRootView(true)
.
In this example, the first test to navigating to a view (which is clicking the plus button, to increment counter by 1), then subsequent test is running checks for the entire view.
CounterInstrumentedTest.kt
package com.example.android.accessibility.counter
import androidx.test.espresso.Espresso
import androidx.test.espresso.accessibility.AccessibilityChecks
import androidx.test.espresso.action.ViewActions
import androidx.test.espresso.assertion.ViewAssertions.matches
import androidx.test.espresso.matcher.ViewMatchers.withId
import androidx.test.espresso.matcher.ViewMatchers.withText
import androidx.test.rule.ActivityTestRule
import androidx.test.ext.junit.runners.AndroidJUnit4
import org.junit.BeforeClass
import org.junit.Rule
import org.junit.Test
import org.junit.runner.RunWith
@RunWith(AndroidJUnit4::class)
class CounterInstrumentedTest {
@Rule
@JvmField
var mActivityTestRule: ActivityTestRule<MainActivity> =
ActivityTestRule(MainActivity::class.java)
@Test
fun navigateToAddToDoScreen() {
Espresso.onView(withId(R.id.add_button)).perform(ViewActions.click())
}
// The following code runs all accessibility checks on all views in the
// hierarchy rooted at that view and throws an exception if any errors are found
@Test
fun performAccessibilityCheckOnAddToDoScreen() {
ImmutableSet<AccessibilityHierarchyCheck> checks =
AccessibilityCheckPreset
.getAccessibilityHierarchyChecksForPreset(AccessibilityCheckPreset.LATEST);
AccessibilityHierarchyAndroid hierarchy = AccessibilityHierarchyAndroid.newBuilder(view).build();
List<AccessibilityHierarchyCheckResult> results = new ArrayList<>();
for (AccessibilityHierarchyCheck check : checks)
{results.addAll(check.runCheckOnHierarchy(hierarchy));
}
List<AccessibilityHierarchyCheckResult> errors =
AccessibilityCheckResultUtils.getResultsForType(results, AccessibilityCheckResultType.ERROR);
if (!errors.isEmpty()) {
throw new RuntimeException(errors.get(0).getMessage().toString());
}
}
companion object {
@BeforeClass
@JvmStatic
fun enableAccessibilityChecks() {
AccessibilityChecks.enable().
.setRunChecksFromRootView(true)
}
}
}
Run script
Navigate to your app root folder and run the usual build and test commands.
./gradlew build
./gradlew test
Espresso HTML report
The report is generated in /build/reports/
directory, and in very comprehensive including performance anomalies and app package versions. Below is the section of report, that is focused on Accessibility issues.
Github Actions example
espresso-accessibility.yml
name: Espresso With Accessibility Check
on:
pull_request:
branches:
- 'main'
push:
branches:
- 'main'
jobs:
build:
runs-on: ubuntu-20.04
name: Espresso Accessibility Check
steps:
- uses: actions/checkout@v4
- uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'
- run: cd ./counterapp_root && ./gradlew build
- run: cd ./counterapp_root && ./gradlew test
- name: Output reports
uses: actions/upload-artifact@v4
if: always()
continue-on-error: true
with:
name: artifacts
path: |
./counterapp_root/app/build/reports/*