在 Android 6.0 上测试通过,但在 Android 8.0 上失败 - androidx.test.espresso.PerformException:执行“单击”时出错

Posted

技术标签:

【中文标题】在 Android 6.0 上测试通过,但在 Android 8.0 上失败 - androidx.test.espresso.PerformException:执行“单击”时出错【英文标题】:Test pass on Android 6.0 but fail on Android 8.0 - androidx.test.espresso.PerformException: Error performing 'single click 【发布时间】:2019-05-10 08:48:21 【问题描述】:

android Studio 3.3

我有两个编辑字段和一个按钮。如果单击按钮但未填写所有字段,则提示错误消息 - Please, input all fields

这里是app/build.gradle:

    ext.ESPRESSO_VERSION = '3.2.0-alpha02'
    androidTestCompile 'com.azimolabs.conditionwatcher:conditionwatcher:0.2'

    androidTestImplementation "androidx.test.espresso:espresso-core:$ESPRESSO_VERSION"
    androidTestImplementation "androidx.test.espresso:espresso-intents:$ESPRESSO_VERSION"
    androidTestImplementation "androidx.test.espresso:espresso-contrib:$ESPRESSO_VERSION"
    androidTestImplementation "androidx.test:rules:$ANDROIDX_TEST"
    androidTestImplementation "androidx.test:runner:$ANDROIDX_TEST"
    androidTestImplementation 'com.squareup.okhttp3:mockwebserver:3.8.0'

    testImplementation 'junit:junit:4.12'

这里的布局:

<?xml version="1.0" encoding="utf-8"?>
<layout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools">

    <data>

    </data>

    <androidx.constraintlayout.widget.ConstraintLayout
        android:layout_
        android:layout_>

        <include
            android:id="@+id/jsonViewToolBar"
            layout="@layout/tool_bar"
            android:title='@@string/add_trader'
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toTopOf="parent" />

        <TextView
            android:id="@+id/baseTextView"
            android:layout_
            android:layout_
            android:layout_margin="@dimen/default_margin"
            android:layout_marginEnd="@dimen/half_default_margin"
            android:text="@string/base"
            android:textSize="@dimen/text_view_text_size"
            app:layout_constraintEnd_toEndOf="parent"
            app:layout_constraintStart_toStartOf="parent"
            app:layout_constraintTop_toBottomOf="@+id/jsonViewToolBar" />

        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/baseTextInputEditText"
            style="@style/textViewOneLine"
            android:layout_
            android:layout_
            android:textSize="@dimen/edit_text_text_size"
            app:layout_constraintEnd_toEndOf="@+id/baseTextView"
            app:layout_constraintStart_toStartOf="@+id/baseTextView"
            app:layout_constraintTop_toBottomOf="@+id/baseTextView" />

        <TextView
            android:id="@+id/quoteTextView"
            android:layout_
            android:layout_
            android:layout_marginTop="@dimen/default_margin"
            android:text="@string/quote"
            android:textSize="@dimen/text_view_text_size"
            app:layout_constraintEnd_toEndOf="@+id/baseTextView"
            app:layout_constraintStart_toStartOf="@+id/baseTextView"
            app:layout_constraintTop_toBottomOf="@+id/baseTextInputEditText" />

        <com.google.android.material.textfield.TextInputEditText
            android:id="@+id/quoteTextInputEditText"
            style="@style/textViewOneLine"
            android:layout_
            android:layout_
            android:textSize="@dimen/edit_text_text_size"
            app:layout_constraintEnd_toEndOf="@+id/baseTextView"
            app:layout_constraintStart_toStartOf="@+id/baseTextView"
            app:layout_constraintTop_toBottomOf="@+id/quoteTextView" />


        <com.google.android.material.button.MaterialButton
            android:id="@+id/startButton"
            android:layout_
            android:layout_
            android:layout_marginTop="@dimen/default_margin"
            android:layout_marginBottom="@dimen/default_margin"
            android:gravity="center"
            android:onClick="@() -> handler.onClickStart()"
            android:text="@string/start"
            android:textSize="@dimen/tool_bar_text_size"
            app:layout_constraintEnd_toEndOf="@+id/baseTextView"
            app:layout_constraintStart_toStartOf="@+id/baseTextView"
            app:layout_constraintTop_toBottomOf="@+id/quoteTextInputEditText"
            app:textAllCaps="true" />

        <include
            layout="@layout/progress_bar_layout"
            android:visibility="gone" />

    </androidx.constraintlayout.widget.ConstraintLayout>

</layout>

这里是 Espresso 的测试:

@Test
    fun onlyQuoteFill_buttonStart_click() 
        onView(withId(baseTextInputEditText)).perform(clearText())
        onView(withId(quoteTextInputEditText)).perform(typeText(QUOTE_TEST))
        onView(withId(startButton))
                .perform(click())
        onView(withText(please_input_all_fields)).inRoot(ToastMatcher())
                .check(matches(isDisplayed()))
    

并且此测试成功通过模拟器 Android 5.0、6.0、7.0

不错。

但是当我在模拟器 Android 8.0 上开始此测试时,它会失败并显示错误消息:

$ adb shell am instrument -w -r   -e debug false -e class 'com.myproject.AddTraderActivityTest#onlyQuoteFill_buttonStart_click' com.myproject.debug.test/androidx.test.runner.AndroidJUnitRunner
Client not ready yet..
Started running tests

androidx.test.espresso.PerformException: Error performing 'single click - At Coordinates: 239, 427 and precision: 16, 16' on view 'with id: com.myproject.debug:id/startButton'.
at androidx.test.espresso.PerformException$Builder.build(PerformException.java:84)
at androidx.test.espresso.base.DefaultFailureHandler.getUserFriendlyError(DefaultFailureHandler.java:87)
at androidx.test.espresso.base.DefaultFailureHandler.handle(DefaultFailureHandler.java:59)
at androidx.test.espresso.ViewInteraction.waitForAndHandleInteractionResults(ViewInteraction.java:316)
at androidx.test.espresso.ViewInteraction.desugaredPerform(ViewInteraction.java:177)
at androidx.test.espresso.ViewInteraction.perform(ViewInteraction.java:118)
at com.myproject.AddTraderActivityTest.onlyQuoteFill_buttonStart_click(AddTraderActivityTest.kt:447)
at java.lang.reflect.Method.invoke(Native Method)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at androidx.test.internal.runner.junit4.statement.RunBefores.evaluate(RunBefores.java:80)
at androidx.test.internal.runner.junit4.statement.RunAfters.evaluate(RunAfters.java:61)
at androidx.test.rule.ActivityTestRule$ActivityStatement.evaluate(ActivityTestRule.java:531)
at org.junit.rules.RunRules.evaluate(RunRules.java:20)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at androidx.test.runner.AndroidJUnit4.run(AndroidJUnit4.java:104)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at androidx.test.internal.runner.TestExecutor.execute(TestExecutor.java:56)
at androidx.test.runner.AndroidJUnitRunner.onStart(AndroidJUnitRunner.java:392)
at android.app.Instrumentation$InstrumentationThread.run(Instrumentation.java:2075)
Caused by: androidx.test.espresso.PerformException: Error performing 'Send down motion event' on view 'unknown'.
at androidx.test.espresso.PerformException$Builder.build(PerformException.java:84)
at androidx.test.espresso.action.MotionEvents.sendDown(MotionEvents.java:127)
at androidx.test.espresso.action.Tap.sendSingleTap(Tap.java:168)
at androidx.test.espresso.action.Tap.access$100(Tap.java:31)
at androidx.test.espresso.action.Tap$1.sendTap(Tap.java:47)
at androidx.test.espresso.action.GeneralClickAction.perform(GeneralClickAction.java:136)
at androidx.test.espresso.ViewInteraction$SingleExecutionViewAction.perform(ViewInteraction.java:360)
at androidx.test.espresso.ViewInteraction.doPerform(ViewInteraction.java:251)
at androidx.test.espresso.ViewInteraction.access$100(ViewInteraction.java:64)
at androidx.test.espresso.ViewInteraction$1.call(ViewInteraction.java:157)
at androidx.test.espresso.ViewInteraction$1.call(ViewInteraction.java:154)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at android.os.Handler.handleCallback(Handler.java:790)
at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:164)
at android.app.ActivityThread.main(ActivityThread.java:6494)
at java.lang.reflect.Method.invoke(Native Method)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:807)
Caused by: androidx.test.espresso.InjectEventSecurityException: java.lang.SecurityException: Injecting to another application requires INJECT_EVENTS permission
at androidx.test.espresso.base.InputManagerEventInjectionStrategy.innerInjectMotionEvent(InputManagerEventInjectionStrategy.java:164)
at androidx.test.espresso.base.InputManagerEventInjectionStrategy.innerInjectMotionEvent(InputManagerEventInjectionStrategy.java:162)
at androidx.test.espresso.base.InputManagerEventInjectionStrategy.injectMotionEvent(InputManagerEventInjectionStrategy.java:130)
at androidx.test.espresso.base.EventInjector.injectMotionEvent(EventInjector.java:92)
at androidx.test.espresso.base.UiControllerImpl$3.call(UiControllerImpl.java:229)
at androidx.test.espresso.base.UiControllerImpl$3.call(UiControllerImpl.java:226)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:457)
at java.util.concurrent.FutureTask.run(FutureTask.java:266)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1162)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:636)
at java.lang.Thread.run(Thread.java:764)
Caused by: java.lang.SecurityException: Injecting to another application requires INJECT_EVENTS permission
at android.os.Parcel.readException(Parcel.java:2004)
at android.os.Parcel.readException(Parcel.java:1950)
at android.hardware.input.IInputManager$Stub$Proxy.injectInputEvent(IInputManager.java:636)
at android.hardware.input.InputManager.injectInputEvent(InputManager.java:925)
at java.lang.reflect.Method.invoke(Native Method)
at androidx.test.espresso.base.InputManagerEventInjectionStrategy.innerInjectMotionEvent(InputManagerEventInjectionStrategy.java:146)
... 11 more


Tests ran to completion.

此处设置Android 8.0设置:

这里是 Android 6.0 的屏幕截图。

这里是 Android 8.0 的屏幕截图

附:当点击按钮开始我不隐藏软键盘。

附言在我开始在具有更高密度 xhdpi 的 Android 8.0 上进行测试后,然后测试 SUCCESS PASS

这里的屏幕截图:

【问题讨论】:

【参考方案1】:

表示在执行 ViewAction 时发生异常 UI 线程。

ViewAction 的描述,正在执行的视图和 原因包含在错误中。注意:FailureHandlers 可以改变 稍后例外以使其更加用户友好。

这通常是不可恢复的,所以它被扔在 检测线程。

更多信息请访问PerformException

【讨论】:

我找到了解决方案。当关注第二个编辑文本时,我在布局和生产代码中添加 ScrollView,我以编程方式向下滚动到屏幕底部。结果现在测试成功通过。 将其作为答案发布并在 2 天内确认【参考方案2】:

我找到了解决方案。我在布局和生产代码中添加ScrollView,当专注于第二个编辑文本时,我以编程方式向下滚动到屏幕底部。结果现在按钮Start 完全可见。结果现在测试是成功通过

【讨论】:

以上是关于在 Android 6.0 上测试通过,但在 Android 8.0 上失败 - androidx.test.espresso.PerformException:执行“单击”时出错的主要内容,如果未能解决你的问题,请参考以下文章

启动 Unity 时应用程序崩溃 - 在 Android Studio 中测试时不会崩溃

使用意图的 Android 6.0 instagram 图像共享不起作用

RNFIREBASE MESSENGER 无法在 iOS 上运行,但在 Android 上运行

Android:通过 Playstore 安装时,Spotify 身份验证在 Android 6.0 上不起作用

在 Genymotion 中测试打盹功能(Android 6.0 Marshmallow)

Flutter HTTP 响应在 Flutter web 上测试时显示完整响应,但在 Android 设备上测试时显示不完整