Android Testing

Handle Android animations properly

Alex Zhukovich 1 min read
Handle Android animations properly
Table of Contents

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.


Mobile development with Alex

A blog about Android development & testing, Best Practices, Tips and Tricks

Share
More from Mobile development with Alex

Great! You’ve successfully signed up.

Welcome back! You've successfully signed in.

You've successfully subscribed to Mobile development with Alex.

Success! Check your email for magic link to sign-in.

Success! Your billing info has been updated.

Your billing was not updated.