Espresso 测试禁用动画

Posted

技术标签:

【中文标题】Espresso 测试禁用动画【英文标题】:Espresso testing disable animation 【发布时间】:2017-05-03 04:28:41 【问题描述】:

@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 无法处理动画,所以我在下面做了。 - 禁用我的测试设备窗口动画、过渡动画和动画持续时间比例都设置为关闭(这不起作用) - 然后我尝试在我的代码中添加一个标志,例如。 espresso_testing = 真。如果为真,我的代码将跳过调用所有 startAnimation() 函数调用。 ---> 这是有效的。但是,要求我在编写 espresso 测试用例时不能更改我的应用程序上的代码。包括上面的一个测试用例。

还有其他方法可以做到这一点吗?提前致谢。

【问题讨论】:

检查这个。它非常快***.com/a/56198539/4797289 【参考方案1】:

确保更新您的插件:

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个设置:

窗口动画比例 过渡动画比例 Animator 持续时间 规模

来源: 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

你可以试试领英的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

您可以尝试为您的 espresso 测试创建 TestRuleGradle 任务:

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

【讨论】:

我是用真机进行测试,以上还适用吗? animationsDisabled 不是未知属性。我只是向您指出了官方文档。你必须有最新的android插件2.3.1 @JaredBurrows,您自己测试过animationsDisabled 标志还是仅仅依靠文档?就我个人而言,我无法使用该标志, 对于其他人:animationsDisabled 等效于运行测试的 am instrument --no-window-animation 和运行测试之前的 adb shell settings put global window_animation_scale 0。要禁用所有动画,请在运行测试之前运行上述答案中的所有三个 adb shell ... 命令。来源:issuetracker.google.com/issues/69247502 animationsDisabled 根据myhexaville.com/2018/01/15/android-espresso-testing 和我刚刚使用 gradle-5.1.1-all.zip 和 com.android.tools.build:gradle:3.4 的经验不起作用。 0.【参考方案2】:

没错,您不应该在生产代码中添加测试代码。这里的问题在于动画。如果您使用HandlersRunnables 执行动画,则无法使用开发人员选项将其关闭。我们使用它来制作动画的常见位置是自定义视图。

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

一个很好的参考是ProgressBar

【讨论】:

我添加了我的设备动画关闭设置屏幕截图。即使使用这些设置,动画测试仍然失败。 非常重要的通知。谢谢【参考方案3】:

1.你在 Gradle 中使用它

android 

  //...

  testOptions 
    animationsDisabled = true
  

  // ...

2。在 ADB for device 中使用

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")
        
    

【讨论】:

【参考方案4】:

你可以看看这个repo

构建项目并下载生成的 .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

这将为您禁用系统动画。

【讨论】:

以上是关于Espresso 测试禁用动画的主要内容,如果未能解决你的问题,请参考以下文章

在 Espresso 中禁用/接受测试存储服务

Espresso 不使用 Gif 动画运行 Activity 测试

Espresso 不适用于 NineOldAndroids 动画?

我们可以在 aws 设备场中为 Android espresso 测试禁用一个对话框吗

带有循环动画的 Espresso 冻结视图

Espresso:如何测试 SwipeRefreshLayout?