Mobile Development 16 min read

How to Build a Full‑Coverage Android UI Test Platform with Espresso

Despite widespread reliance on manual UI testing, this article details how the author’s team built an Espresso‑based test platform that achieves 80‑90% functional coverage, introduces the ETP design, explains single‑page testing, test flows, and shares practical solutions to common Espresso pitfalls.

Hujiang Technology
Hujiang Technology
Hujiang Technology
How to Build a Full‑Coverage Android UI Test Platform with Espresso

Espresso Overview

Espresso is Google’s open‑source Android UI testing framework, released in 2013. It integrates with JUnit and allows developers and testers to write concise UI tests that can cover 80‑90% of functional scenarios.

Espresso Test Platform (ETP) Design

The team built a custom test platform called ETP (Espresso Test Platform) to improve flexibility and reusability. Instead of writing one monolithic test per user flow, tests are split into independent single‑page units that can be combined into larger test flows.

Single‑Page Testing

A single‑page test targets a single Activity or Fragment and validates only the logic of that page. Navigation checks are allowed, but downstream interactions are not exercised. Because Espresso runs on JUnit, multiple independent tests for the same page can be executed in random order.

To achieve full coverage, each single‑page test must contain branches for all possible app states (e.g., logged‑in vs. logged‑out) within the same test file.

Page Association Testing

Test subscription actions on the subscription page and verify success on that page.

On the subscription list page, simulate a successful subscription notification and verify that the new item appears.

Activity with Multiple Fragments

Although Espresso treats an Activity as the entry point, each Fragment is treated as an independent single‑page test. For an app with three tabs plus a main activity, four single‑page tests are defined.

Random Trigger Logic

Global broadcasts may trigger unrelated pop‑ups that interrupt tests. The solution is to write dedicated tests for such pop‑ups and control global flags to disable them during other tests.

Test Flow and Full‑Feature Coverage

After all single‑page tests are written, they are sequenced into test flows . A flow is an ordered execution where the output of one page becomes the input for the next (e.g., login before accessing protected pages).

A test flow strings together different single‑page tests.

One flow can represent a complete business process, covering multiple test cases.

Multiple flows test different logical branches of the same page.

Overlaying flows ensures every page’s logic is exercised, achieving near‑complete functional coverage.

Espresso Pitfalls and Workarounds

IdlingResource Requires a Following UI Action

IdlingResource callbacks are only triggered when a UI operation follows the asynchronous task. If the background work finishes and the screen is closed without a subsequent onView call, the IdlingResource will never report idle, making such scenarios untestable.

Thread‑Specific IdlingResource Bug

Espresso runs on a test thread distinct from the app’s main thread. Code that must execute on the UI thread must be wrapped with runOnUiThread. In some cases the IdlingResource receives the completion callback on the app thread but fails to notify the test thread, causing missed idle notifications.

mActivityTestRule.getActivity().runOnUiThread(new Runnable() {
    @Override
    public void run() {
        LogUtils.d(TAG, "runOnUiThread..." + Thread.currentThread());
        TaskApi.Companion.getMyTasks(0, 10000, "", new HSAPICallback<TaskListResult>() {
            @Override
            public void onRequestSuccess(TaskListResult data, int httpStatus, Boolean fromCache) {
                super.onRequestSuccess(data, httpStatus, fromCache);
                mTasks = data.getDatas();
            }
        });
    }
});

hasProperty Exception

Hamcrest’s hasProperty matcher fails on Android because the SDK lacks the full JavaBeans library, resulting in NoClassDefFoundError: java/beans/Introspector. The team resolved this by implementing a custom matcher instead of using hasProperty.

DrawerLayout Timing Issue

DrawerLayout introduces a 160 ms delay before its peek animation. Espresso’s perform(click()) sends down/up events asynchronously, which can exceed this window, causing the click to be ignored. The workaround disables the delayed callback via an AOP pointcut that removes the pending runnable.

@Pointcut("execution(* android.support.v4.widget.DrawerLayout.ViewDragCallback.onEdgeTouched(..))")
public void edgeTouchedPoint() {}

@After("edgeTouchedPoint()")
public void onExecutionPoint(final JoinPoint joinPoint) throws Throwable {
    Reflect.on(joinPoint.getTarget()).call("removeCallbacks");
}

Conclusion

Extensive experimentation shows that Espresso, when combined with the single‑page and test‑flow methodology, can achieve near‑complete functional coverage. The approach has already uncovered numerous bugs caused by careless development, improving test efficiency and product quality.

References

https://google.github.io/android-testing-support-library/docs/espresso/index.html

http://stackoverflow.com/questions/33120493/espresso-idling-resource-doesnt-work

http://baiduhix.blogspot.com/2015/07/android-espresso-ondata-error.html

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

Mobile DevelopmentAndroidtest automationEspressoIdlingResourceUI testing
Hujiang Technology
Written by

Hujiang Technology

We focus on the real-world challenges developers face, delivering authentic, practical content and a direct platform for technical networking among developers.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.