Before doing some Android testing with Espresso, we need to prepare our devices and turn off the following animations:

  • Window animation scale
  • Transition animation scale
  • Animator duration scale

We can do it manually. To do this, we need to open the developer options and set Window animation scale, Transition animation scale and Animator duration scale to "Animation scale off".

Such way can create additional problems for us. In particular, when we have device farm this will lead to a lot of maintenance. Fortunately, we can set animation scale using ADB(Android Debug Bridge):

adb shell settings put global window_animation_scale 0
adb shell settings put global transition_animation_scale 0
adb shell settings put global animator_duration_scale 0

However, it doesn't mean that everything will work fine out of the box, we still need to adapt our code.

Necessary permissions are needed in the AndroidManifest.xml:

<uses-permission android:name="android.permission.SET_ANIMATION_SCALE"/>

Now we can just grant SET_ANIMATION_SCALE before running tests:

val packageName = InstrumentationRegistry.getTargetContext().packageName
UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
        .executeShellCommand("pm grant $packageName android.permission.SET_ANIMATION_SCALE")

It allows us to disable animation before running tests and enable them after they are finished. Unfortunately, in such case, minimal API level would be 21.

There is another way, checking animation scale in the code, and enable/disable animations appropriately:

val animatorScale = Settings.Global.getFloat(
    contentResolver,
    Settings.Global.ANIMATOR_DURATION_SCALE,
    0.0f
)

button.setOnClickListener {
    if (animatorScale != 0.0f) {
        textView.animate()
            .alpha(1.0f)
            .setListener(object : AnimatorListenerAdapter() {
                override fun onAnimationEnd(animation: Animator) {
                    super.onAnimationEnd(animation)
                    textView.visibility = View.VISIBLE
                }
            })
            .duration = 4000
    } else {
        textView.visibility = View.VISIBLE
    }
}

It means that we should do more work because because we should handle all animations in our code, but it gives us more flexibility.

As you can see, we have many options for preparing devices for Espresso testing. As a benefit, you can get less flaky tests.