0

I am creating a user interface test for an Android app. The test taps a UI element and expects another UI element to appear. The test will only pass if I include a Thread.sleep after tapping the first UI element. How can I avoid this?

Here's the test:

@Test
public void mapInfoIsDisplayed() throws InterruptedException {
    
    // Tap on the crosshair at the centre of the map.
    onView(withId(R.id.map_crosshairs)).perform(click());

    Thread.sleep(100); // Why is this required?

    // Verify that the view is displayed
    onView(withId(R.id.feature_title)).check(matches(isCompletelyDisplayed()));
}

The app is written in RxJava, uses Hilt for dependency injection and Espresso as the UI testing framework.

I want the test dependencies to run synchronously on the main thread so my test uses:

  1. the trampoline scheduler for RxJava during tests (executes on the calling thread)
  2. an in-memory Room database which allows queries on the main thread

I have also disabled animations through the emulator settings and have also added the following to my build.gradle (although I'm not sure it does anything):

testOptions {
    animationsDisabled = true
}

With all this I would expect the test to run synchronously, waiting for any dependent threads to finish before testing for whether my the new view is displayed. This doesn't appear to be happening so I'm left with a flaky test.

I have a strong suspicion that the production code is being executed asynchronously somewhere, the problem is I can't pinpoint where (it'd be great if there was some way in Android Studio to find this).

How can I ensure all code is executed synchronously, thus avoiding the Thread.sleep?

donturner
  • 17,867
  • 8
  • 59
  • 81
  • 2
    I don't have time to write a proper reply, but you're going to want to look in to the likes of "idling resources." – Mike Collins Sep 10 '20 at 14:54
  • 1
    Alternately, you may need to roll your own waiter. A pattern for this can be found at https://stackoverflow.com/questions/21417954/espresso-thread-sleep. Even if that particular one doesn’t work for you, it should help get the ball rolling. – Mike Collins Sep 10 '20 at 15:00
  • I agree with @Mike take a look at this https://developer.android.com/training/testing/espresso/idling-resource – cdevansh Sep 10 '20 at 15:25
  • Thanks Mike, yes good point about idling resources, and this could definitely work, however, at this stage I'm more interested to know why my code isn't running synchronously and see if I can fix that first. – donturner Sep 10 '20 at 15:27
  • I'm sure is it running synchronously, but too quickly, which is why you need your sleep. I've never seen an Espresso framework not need some solution for waiting. – Mike Collins Sep 10 '20 at 16:03

0 Answers0