11

this is regarding Espresso. I am successfully running integration test on a simulator. I think some tests are failing because it's running too fast. Is there a way to slowdown the execution/playback speeD?

SIr Codealot
  • 5,331
  • 9
  • 33
  • 45

5 Answers5

7

It's impossible that a test fails cause to speed. Espresso can synchronize all test operations with the application under test. By default, Espresso waits for UI events in the current message queue to process and default AsyncTasks to complete before it moves on to the next test operation. However if this is not enough for your application you can tell Espresso when to be idle and when not. To do so you have to :

  • Implement the IdlingResource interface.
  • Register one or more of your IdlingResource(s) with Espresso by calling Espresso.registerIdlingResource in test setup.

If you need more help ask me!!

Hongbin Wang
  • 1,186
  • 2
  • 14
  • 34
Lorenzo Camaione
  • 505
  • 3
  • 15
1

When you record an Espresso Test in Android Studio it will automatically add Sleep statements to tests when there is view interaction to handle the delay. This is the approach that is generated along with the comments:

// Added a sleep statement to match the app's execution delay.
// The recommended way to handle such scenarios is to use Espresso idling resources:
// https://google.github.io/android-testing-support-library/docs/espresso/idling-resource/index.html

try {
    Thread.sleep(700);
} catch (InterruptedException e) {
    e.printStackTrace();
}

Link to the docs

robotsquidward
  • 163
  • 2
  • 16
0

I had this problem too. I solved by removing activity animation on my device from Developer options.

If your problem is still there you can use sleep in your test to slow down.

SystemClock.sleep(1000);

enter image description here

Johnny
  • 2,989
  • 4
  • 17
  • 28
0

Haha...actually Espresso works like this only. The problem you are facing is that UI events are not able to complete (For example, clicking a list item before the list loads from a network call). In this case, where your resources are being loaded from other thread, you can actually perform Thread.sleep(millis) or more efficiently UiController's loopMainThreadForAtleast(millis) method to wait for something to load (event to complete).

Akshay Mahajan
  • 2,064
  • 1
  • 17
  • 20
0

All the previous recommendations are problematic because your sleeps are either very conservative, or you get spurious failures depending on the performance of your platform. Instead, try a loop, waiting for your view resource to be available (and error if it isn't available after a while). I've put a function at the bottom for your use.

You could use this code like this (filling out a text field for example):

waitForView { onView(withId(YOUR_VIEW_ID)).perform(clearText(),typeText("TEST TEXT"), pressImeActionButton(), pressBack()) }

fun<T> waitForView(time: Int = 5000, thunk: ()->T) : T
    {
        var countup = 0
        while(true) try
        {
            return thunk()
        }
        catch (e: NoMatchingViewException)
        {
            if (countup >= time)
            {
                println("After delay of $time, there is still no matching view")
                throw e
            }
            sleep(500)
            countup += 500
        }
        catch (e: PerformException)
        {
            sleep(500)
            countup += 500
        }
    }
AndrewStone
  • 517
  • 4
  • 14