运行 Espresso 测试时如何在代码中禁用动画

How to disable animations in code when running Espresso tests

有人在 运行ning Espresso 测试时通过代码 设法禁用动画吗?我一直在尝试按照此网页中的说明进行操作(链接至 here):
https://code.google.com/p/android-test-kit/wiki/DisablingAnimations

不幸的是它似乎没有工作,因为我一直看到这个权限错误:

04-27 15:48:28.694      303-342/system_process W/PackageManager﹕ Not granting permission android.permission.SET_ANIMATION_SCALE to package com.cookbrite.dev (protectionLevel=50 flags=0x18be46)

我真的希望避免重新配置我的 device/emulators。我们经常 运行 在本地进行单独测试,如果我必须不断切换设置,这会让我很烦。

我注意到其他一些开发人员抱怨这不起作用,所以我可能并不孤单:
https://groups.google.com/forum/#!msg/android-test-kit-discuss/TCil7kMQRTM/QK1qCjzM6KQJ

我终于让它工作了。这是一个列出所需步骤的要点:
https://gist.github.com/daj/7b48f1b8a92abf960e7b

我错过的关键步骤是 运行 adb 授予权限:

adb shell pm grant com.mypackage android.permission.SET_ANIMATION_SCALE    

将权限添加到清单和 运行 反射步骤本身似乎还不够。

我正在为每种动画类型执行这三个命令,它们对我有用:

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

此处有更多信息 - prepare android emulator for UI test automation.

更好的方法是更新 app/build.gradle如果您 运行 从命令行进行测试

android {
    ...
    ...

    testOptions {
        animationsDisabled = true
    }
}

您可能需要在重建之前执行 ./gradlew clean。如果您使用 android studio,假设 apk 中没有任何变化,它可能不会更新您设备上的 apk。注意这些以确保更改确实在您的设备上生效。

另请阅读文档 here

Disables animations during instrumented tests you run from the cammand line.

If you set this property to true, running instrumented tests with Gradle from the command line executes am instrument with the --no-window-animation flag. By default, this property is set to false.

This property does not affect tests that you run using Android Studio.

这样使用:


1.您在 Gradle

中使用它
android {

  //...

  testOptions {
    animationsDisabled = true
  }

  // ...
}

2。在 ADB 中用于设备

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 &

3。使用规则

class DisableAnimationsRule : TestRule {
    override fun apply(base: Statement, description: Description): Statement {
        return object : Statement() {
            @Throws(Throwable::class)
           override fun evaluate() {
                // disable animations for test run
                changeAnimationStatus(enable = false)
                try {
                    base.evaluate()
                } finally {
                    // enable after test run
                    changeAnimationStatus(enable = true)
                }
            }
        }
    }

    @Throws(IOException::class)
    private fun changeAnimationStatus(enable:Boolean = true) {
        with(UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())){
            executeShellCommand("settings put global transition_animation_scale ${if(enable) 1 else 0}")
            executeShellCommand("settings put global window_animation_scale ${if(enable) 1 else 0}")
            executeShellCommand("settings put global animator_duration_scale ${if(enable) 1 else 0}")
        }
    }
}