콘텐츠로 건너뛰기

자주 방문한 페이지

최근 방문한 페이지

navigation

Espresso Idling Resources

An idling resource represents an asynchronous operation whose results affect subsequent operations in a UI test. By registering idling resources with Espresso, you can validate these asynchronous operations more reliably when testing your app.

Identifying when idling resources are needed

Espresso provides a sophisticated set of synchronization capabilities. This characteristic of the framework, however, applies only to operations that post messages on the MessageQueue, such as a subclass of View that's drawing its contents on the screen.

Because Espresso isn't aware of any other asynchronous operations, including those running on a background thread, Espresso can't provide its synchronization guarantees in those situations. In order to make Espresso aware of your app's long-running operations, you must register each one as an idling resource.

If you don't use idling resources when testing the results of your app's asynchronous work, you might find yourself having to use one of the following bad workarounds to improve your tests' reliability:

Espresso allows you to remove these unreliable workarounds from your tests and instead register your app's asynchronous work as idling resources.

Common use cases

When performing operations similar to the following examples in your tests, consider using an idling resource:

It's especially important to register idling resources when these operations update a UI that your tests then validate.

Example idling resource implementations

The following list describes several example implementations of idling resources that you can integrate into your app:

CountingIdlingResource
Maintains a counter of active tasks. When the counter is zero, the associated resource is considered idle. This functionality closely resembles that of a Semaphore. In most cases, this implementation is sufficient for managing your app's asynchronous work during testing.
UriIdlingResource
Similar to CountingIdlingResource, but the counter needs to be zero for a specific period of time before the resource is considered idle. This additional waiting period takes consecutive network requests into account, where an app in your thread might make a new request immediately after receiving a response to a previous request.
IdlingThreadPoolExecutor
A custom implementation of ThreadPoolExecutor that keeps track of the total number of running tasks within the created thread pools. This class uses a CountingIdlingResource to maintain the counter of active tasks.
IdlingScheduledThreadPoolExecutor
A custom implementation of ScheduledThreadPoolExecutor. It provides the same functionality and capabilities as the IdlingThreadPoolExecutor class, but it can also keep track of tasks that are scheduled for the future or are scheduled to execute periodically.

Creating your own idling resource

As you use idling resources in your app's tests, you might need to provide custom resource management or logging. In those cases, the implementations listed in the previous section might not suffice. If that's the case, you can extend one of these idling resource implementations or create your own.

If you implement your own idling resource functionality, keep the following best practices in mind, particularly the first one:

Invoke transitions to the idle state outside idle checks.
After your app becomes idle, call onTransitionToIdle() outside any implementations of isIdleNow(). That way, Espresso doesn't make a second, unnecessary check to determine whether a given idling resource is idle.

The following code snippet illustrates this recommendation:

public void isIdle() {
    // DON'T call callback.onTransitionToIdle() here!
}

public void backgroundWorkDone() {
    // Background work finished.
    callback.onTransitionToIdle() // Good. Tells Espresso that the app is idle.

    // Don't do any post-processing work beyond this point. Espresso now
    // considers your app to be idle and moves on to the next test action.
}
Register idling resources before you need them.

The synchronization benefits associated with idling resources only take effect following Espresso's first invocation of that resource's isIdleNow() method.

The following list shows several examples of this property:

  • If you register an idling resource in a method annotated with @Before, the idling resource takes effect in the first line of each test.
  • If you register an idling resource inside a test, the idling resource takes effect during the next Espresso-based action. This behavior still occurs even if the next action is in the same test as the statement that registers the idling resource.
Unregister idling resources after you're done using them.

To conserve system resources, you should unregister idling resources as soon as you don't need them anymore. For example, if you register an idling resource in a method annotated with @Before, it's best to unregister this resource in a corresponding method that's annotated with @After.

Use an idling registry to register and unregister idling resources.

By using this container for your app's idling resources, you can register and unregister idling resources repeatedly as needed and still observe consistent behavior.

Maintain only simple app state within idling resources.

For example, the idling resources that you implement and register shouldn't contain references to View objects.

Registering idling resources

Espresso provides a container class into which you can place your app's idling resources. This class, called IdlingRegistry, is a self-contained artifact that introduces minimal overhead to your app. The class also allows you to take the following steps toward improving your app's maintainability:

Integrating idling resources into your app

Although you can add idling resources to an app in several different ways, one approach in particular maintains encapsulation for your app while still allowing you to specify a particular operation that a given idling resource represents.

When adding idling resources into your app, we highly recommend performing only the registration and unregistration operations in your tests and placing the idling resource logic itself in your app's production code.

Although you create the unusual situation of using a test-only interface in production code by following this approach, you can wrap idling resources around code that you already have, maintaining your app's APK size and method count.

Alternative approaches

If you'd prefer to not have idling resources logic in your app's production code, there are several other viable integration strategies:

이 사이트는 쿠키를 사용하여 사이트별 언어 및 표시 옵션에 대한 환경설정을 저장합니다.

Google Play에서 성공을 거두는 데 도움이 되는 최신 Android 개발자 뉴스 및 도움말을 받아 보세요.

* 필수 입력란

완료되었습니다.

WeChat에서 Google Developers 팔로우하기

이 사이트를 (으)로 탐색할까요?

페이지를 요청했지만 이 사이트의 언어 환경설정은 입니다.

언어 환경설정을 변경하고 이 사이트를 (으)로 탐색할까요? 언어 환경설정을 나중에 변경하려면 각 페이지 하단의 언어 메뉴를 사용하세요.

이 클래스를 사용하려면 API 수준 이상이 필요합니다.

문서에 대해 선택한 API 수준이 이므로 이 문서가 표시되지 않습니다. 왼쪽 탐색 메뉴의 선택기로 문서 API 수준을 변경할 수 있습니다.

앱에 필요한 API 수준 지정에 관한 자세한 내용은 다양한 플랫폼 버전 지원을 참조하세요.

Take a short survey?
Help us improve the Android developer experience. (April 2018 — Developer Survey)