Espresso测试禁用动画

35

在此输入图片描述

@Test
    public void test3_PaySuccessful(){
        init();

    ViewInteraction amountEditText = onView(
            allOf(withId(R.id.et_amount), isDisplayed()));
    amountEditText.perform(replaceText("SGD 0.010"), closeSoftKeyboard());

    //, withText("Proceed")
    ViewInteraction appCompatButton = onView(
            allOf(withId(R.id.btn_confirm), isDisplayed()));
    appCompatButton.perform(click());

    //, withText("Pay")
    ViewInteraction appCompatButton2 = onView(
            allOf(withId(R.id.btn_confirm), isDisplayed()));
    appCompatButton2.perform(click());

    //dialog
    ViewInteraction appCompatButton3 = onView(
            allOf(withId(R.id.confirm_button), withText("Confirm"), isDisplayed()));
    appCompatButton3.perform(click());

    //have to disable animation in order to pass this.
    intended(CoreMatchers.allOf(hasComponent(PaymentSelectionActivity2.class.getName())));

}

我在进行包含动画的Espresso测试时遇到了问题,我知道Espresso无法处理动画,因此我做了以下操作: - 关闭我的测试设备的窗口动画、转换动画和动画器持续时间比例,全部设置为OFF(这个方法没有起作用) - 然后我尝试在我的代码中添加一个标志,例如espresso_testing = true。如果为true,则我的代码将跳过调用所有startAnimation()函数调用。--->这个方法有效。但是,在编写Espresso测试用例时,有一个要求,即我不能更改我的应用程序上的代码。以上是一个测试案例。

还有其他方法吗?谢谢!


请检查这个。它非常快 https://stackoverflow.com/a/56198539/4797289 - Rasoul Miri
4个回答

99

请确保及时更新您的插件:

buildscript {
  repositories {
    google()
    gradlePluginPortal()
  }

  dependencies {
    classpath 'com.android.tools.build:gradle:3.3.0'
  }
}

testOptions中使用名为animationsDisabled的新标志:

android {

  ...

  testOptions {
    animationsDisabled = true
  }
}

来源: https://google.github.io/android-gradle-dsl/current/com.android.build.gradle.internal.dsl.TestOptions.html#com.android.build.gradle.internal.dsl.TestOptions:animationsDisabled

您可以尝试手动关闭设备/模拟器上的动画效果:

为了避免测试时出现不稳定性,我们强烈建议在用于测试的物理或虚拟设备上关闭系统的动画效果。在您的设备上,转到"设置 > 开发人员选项",然后关闭以下3个设置:

窗口动画比例、过渡动画比例和动画持续时间

来源: https://developer.android.com/training/testing/espresso/setup#set-up-environment

您可以尝试通过命令行使用adb

# Turn off animations
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 &

来源:https://github.com/jaredsburrows/android-gif-example/blob/master/.travis.yml#L34

你可以尝试使用 LinkedIn 的 TestButler

TestButler.verifyAnimationsDisabled(InstrumentationRegistry.getTargetContext());

来源: https://github.com/linkedin/test-butler/blob/master/test-butler-demo/src/androidTest/java/com/linkedin/android/testbutler/demo/AnimationDisablerTest.java#L26

您可以尝试创建一个 TestRuleGradle 任务来进行 Espresso 测试:

来源: https://product.reverb.com/disabling-animations-in-espresso-for-android-testing-de17f7cf236f


2
animationsDisabled 不是未知属性。我只是指向了官方文档。你必须拥有最新的 Android 插件 2.3.1 - Jared Burrows
4
@JaredBurrows,你是自己测试过animationsDisabled标志,还是仅依赖于文档?个人而言,我无法利用该标志。 - azizbekian
2
对于其他人而言,“animationsDisabled”等同于在运行测试之前执行“am instrument --no-window-animation”和“adb shell settings put global window_animation_scale 0”。要禁用所有动画,请在运行测试之前运行上述答案中的三个“adb shell ...”命令。来源:https://issuetracker.google.com/issues/69247502 - R. Zagórski
1
请注意,文档中指出:"此属性不会影响您使用Android Studio运行的测试。" - Michael Osofsky
显示剩余6条评论

7
你有三个不同的选择:
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}")
        }
    }
}

3
你列出步骤的方式让人看起来好像必须要按照所有步骤才能禁用动画,但实际上它们都是彼此的替代方案。这就是为什么添加描述很有帮助的原因。 - Farid

5

确实,你不应该在生产代码中添加测试代码。问题在于动画。如果您使用 HandlersRunnables 进行动画处理,则无法使用开发者选项关闭它们。我们通常在自定义视图中使用它来执行动画。

但即使在自定义视图中,确保您使用 ValueAnimatorObjectAnimatorAnimatorSet 来执行您的动画。只有这样才能通过在开发者选项中关闭 Animator duration scale 来关闭动画。

ProgressBar 是一个很好的参考。


我添加了我的设备动画关闭设置截图。即使有这些设置,测试仍然在动画上失败。 - kggoh
非常重要的通知。谢谢。 - Lars

2
你可以查看这个repo:https://github.com/finn-no/android_emulator_hacks 构建该项目并下载生成的.apk文件,按照该项目中提到的说明禁用动画,之后就可以顺利使用了。你也可以从许多其他来源下载相同的.apk文件。 一旦你有了.apk文件,然后执行以下命令:
adb install -r android_emulator_hacks.apk
adb shell pm grant no.finn.android_emulator_hacks android.permission.SET_ANIMATION_SCALE
adb shell am start -n no.finn.android_emulator_hacks/no.finn.android_emulator_hacks.HackActivity

这将帮助你关闭系统动画。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接