Espresso wait for network call

19 February 2020 Stephan Petzl Leave a comment Tech-Help

By default you don’t need to take care to handle waiting for activities. But there’s an exception which can make Espresso tests fail. In this article you learn why this happens and how you can handle it.

An example of Espresso wait for network call

Let’s consider this example:

// MainActivity.kt:
...
start_activity_button.setOnClickListener {
    val intent = Intent(context, LoginActivity::class.java)
    Thread.sleep(2000)
    startActivity(intent)
}

This testing code will run just fine:

// LoginTest.kt: 
...
@Rule @JvmField
val activityRule: ActivityTestRule = ActivityTestRule(MainActivity::class.java,true, false)

@Test
fun shouldLoginUser(){
    activityRule.launchActivity(Intent())
    onView(withId(R.id.start_activity_button)).perform(click())
    onView(withId(R.id.et_email)).perform(typeText("mytestemail@email.com")).perform(closeSoftKeyboard())
    onView(withId(R.id.et_password)).perform(typeText("12345678")).perform(closeSoftKeyboard())
    onView(withId(R.id.bt_login)).perform(click())
    Intents.intended(IntentMatchers.hasComponent(MainActivity::class.java!!.getName()))
}

Espresso will know that it needs to wait for the UI thread to get idle BEFORE looking up the R.id.et_email view. Thread.sleep does not change that, since it keeps the current thread (the UI thread) busy.

However, let’s say we would need to make a network call before opening the LoginActivity:

// MainActivity.kt:
...
start_activity_button.setOnClickListener {
    val intent = Intent(context, LoginActivity::class.java)

    // using kotlin coroutines to simulate waiting for a network request on a different thread:
    val job = GlobalScope.launch {
        delay(2000)
    }
    job.invokeOnCompletion {
        startActivity(intent)
    }
}

This would cause Espresso to fail with an exception:

E/TestRunner: androidx.test.espresso.NoMatchingViewException: No views in hierarchy found matching: with id: my.app.com:id/et_email

The problem with Espresso and network calls

Espresso can’t handle network calls automatically because it is not aware of other threads executing a network call. The default way to fix this is to use an IdlingResource for that. In this particular case we could use the android counting idling resource implementation to solve the issue.

Here is an example on how to create such an idling resource.

Like this article? there’s more where that came from!

Leave a Reply