Android测试:等待视图层次结构的根具有窗口焦点

Kim*_*mmy 10 android automated-tests android-espresso android-uiautomator

在Android Ui测试中,我想在对话框中单击一个微调项目,但它会弹出以下错误:

va.lang.RuntimeException: Waited for the root of the view hierarchy to have window focus and not be requesting layout for over 10 seconds. If you specified a non default root matcher, it may be picking a root that never takes focus. Otherwise, something is seriously wrong. Selected Root:
Root{application-window-token=android.view.ViewRootImpl$W@2dac97c7, window-token=android.view.ViewRootImpl$W@2dac97c7, has-window-focus=false, layout-params-type=1, layout-params-string=WM.LayoutParams{(0,0)(fillxfill) sim=#10 ty=1 fl=#81810100 pfl=0x8 wanim=0x1030461 surfaceInsets=Rect(0, 0 - 0, 0) mwfl=0x0}, decor-view-string=MultiPhoneDecorView{id=-1, visibility=VISIBLE, width=1600, height=2560, has-focus=true, has-focusable=true, has-window-focus=false, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}}
. All Roots:
Root{application-window-token=android.view.ViewRootImpl$W@3c913e1, window-token=android.view.ViewRootImpl$W@21b23506, has-window-focus=true, layout-params-type=1002, layout-params-string=WM.LayoutParams{(310,600)(722x480) gr=#10000033 sim=#1 ty=1002 fl=#1860200 fmt=-3 wanim=0x10302db surfaceInsets=Rect(0, 0 - 0, 0) mwfl=0x0}, decor-view-string=PopupViewContainer{id=-1, visibility=VISIBLE, width=722, height=480, has-focus=true, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}}
Root{application-window-token=android.view.ViewRootImpl$W@3c913e1, window-token=android.view.ViewRootImpl$W@3c913e1, has-window-focus=false, layout-params-type=2, layout-params-string=WM.LayoutParams{(0,0)(wrapxwrap) gr=#11 sim=#20 ty=2 fl=#1800002 pfl=0x8 fmt=-3 wanim=0x1030462 surfaceInsets=Rect(0, 0 - 0, 0) mwfl=0x10}, decor-view-string=DecorView{id=-1, visibility=VISIBLE, width=1136, height=1058, has-focus=true, has-focusable=true, has-window-focus=false, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}}
Root{application-window-token=android.view.ViewRootImpl$W@2dac97c7, window-token=android.view.ViewRootImpl$W@2dac97c7, has-window-focus=false, layout-params-type=1, layout-params-string=WM.LayoutParams{(0,0)(fillxfill) sim=#10 ty=1 fl=#81810100 pfl=0x8 wanim=0x1030461 surfaceInsets=Rect(0, 0 - 0, 0) mwfl=0x0}, decor-view-string=MultiPhoneDecorView{id=-1, visibility=VISIBLE, width=1600, height=2560, has-focus=true, has-focusable=true, has-window-focus=false, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}}
at android.support.test.espresso.base.RootViewPicker.get(RootViewPicker.java:99)
at android.support.test.espresso.ViewInteractionModule.provideRootView(ViewInteractionModule.java:69)
at android.support.test.espresso.ViewInteractionModule_ProvideRootViewFactory.get(ViewInteractionModule_ProvideRootViewFactory.java:23)
at android.support.test.espresso.ViewInteractionModule_ProvideRootViewFactory.get(ViewInteractionModule_ProvideRootViewFactory.java:9)
at android.support.test.espresso.base.ViewFinderImpl.getView(ViewFinderImpl.java:68)
at android.support.test.espresso.ViewInteraction$1.run(ViewInteraction.java:120)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:422)
at java.util.concurrent.FutureTask.run(FutureTask.java:237)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:6117)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1399)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1194)
Run Code Online (Sandbox Code Playgroud)

我试过了

onData(allOf(is(instanceOf(String.class)),containsString("A4"))).inRoot(isPlatformPopup()).perform(click());
Run Code Online (Sandbox Code Playgroud)

onView(withText(containsString("A4"))).inRoot(isFocusable()).check(matches(isDisplayed()));
Run Code Online (Sandbox Code Playgroud)

onView(withText(containsString("A4"))).inRoot(withDecorView(not(getActivity().getWindow().getDecorView()))).check(matches(isDisplayed()));
Run Code Online (Sandbox Code Playgroud)

但它们都不起作用......有人能告诉我如何获得ralavant root吗?

Mr-*_*IDE 15

当显示系统对话框时会发生此错误 - 例如“关闭电源”或“不幸的是,启动器已停止”(后台应用程序崩溃) - 并且您尝试在该对话框可见时运行 Espresso 单元测试。

Android 系统对话框:不幸的是,Launcher 已停止。

图片来源:Android 4.0 模拟器总是有一个崩溃的启动器?

您可以通过在运行测试之前关闭系统对话框在代码中解决它:

MyActivity activityUnderTest = activityTestRule.getActivity();
activityUnderTest.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
Run Code Online (Sandbox Code Playgroud)

或者使用 adb 在命令行上发送广播:

adb shell am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS
Run Code Online (Sandbox Code Playgroud)

另一个导致错误的原因是当后台应用程序被冻结 ( ANR ) 或运行缓慢,并且出现一个系统对话框时"Application Isn't Responding. Do you want to close it? [Wait] [OK]"

Android 系统对话框:启动器没有响应。 你想关闭它吗? 等等好吗

图片来源:https : //engineering.linkedin.com/blog/2016/08/introducing-and-open-sourcing-test-butler--reliable-android-test

如果您在此对话框可见时尝试运行 Espresso 测试,它们都将失败并显示“Waited for the root...”错误。没有简单的方法可以以编程方式关闭此对话框。Espresso 无法点击这些按钮,原因如下: Dismiss Alert Dialog in Android Espresso Test。但是,一种方法是使用UIAutomator在对话框中按下“等待”按钮,就在测试开始之前:

应用程序/build.gradle

MyActivity activityUnderTest = activityTestRule.getActivity();
activityUnderTest.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));
Run Code Online (Sandbox Code Playgroud)

ActivityUiTest.kt

adb shell am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS
Run Code Online (Sandbox Code Playgroud)

ActivityUiTest.java

dependencies {
    ...
    androidTestImplementation "androidx.test.uiautomator:uiautomator:2.2.0"
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以在命令行上使用 adb 发送屏幕点击击键以关闭它。例如:

companion object {
    @JvmStatic
    @BeforeClass
    fun dismissANRSystemDialog() {
        val device = UiDevice.getInstance(getInstrumentation())
        // If running the device in English Locale
        var waitButton = device.findObject(UiSelector().textContains("wait"))
        if (waitButton.exists()) {
            waitButton.click()
        }
        // If running the device in Japanese Locale
        waitButton = device.findObject(UiSelector().textContains("??"))
        if (waitButton.exists()) {
            waitButton.click()
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

或者

@BeforeClass
public static void dismissANRSystemDialog() throws UiObjectNotFoundException {
    UiDevice device = UiDevice.getInstance(getInstrumentation());
    // If the device is running in English Locale
    UiObject waitButton = device.findObject(new UiSelector().textContains("wait"));
    if (waitButton.exists()) {
        waitButton.click();
    }
    // If the device is running in Japanese Locale
    waitButton = device.findObject(new UiSelector().textContains("??"));
    if (waitButton.exists()) {
        waitButton.click();
    }
}
Run Code Online (Sandbox Code Playgroud)

更多信息:


Ste*_*nTo 6

当我在DialogFragment中使用Spinner时,我遇到了同样的错误.这是唯一适合我的代码:

onView(withText(containsString("A4"))).inRoot(isPlatformPopup()).check(matches(isDisplayed()));
Run Code Online (Sandbox Code Playgroud)


Jam*_*man 5

当对话框弹出窗口包含微调器项目(下拉列表)时,我遇到了类似的问题,我的单击无法在任何微调器项目上执行并出现相同的错误。我通过使用 onData() 方法和 RootMatchers 找到了一个解决方案:

onData(anything()).inRoot(RootMatchers.isPlatformPopup()).atPosition(1).perform(click());
Run Code Online (Sandbox Code Playgroud)

请注意, atPosition()中的索引值是微调器列表中项目的索引值。


归档时间:

查看次数:

5912 次

最近记录:

7 年,5 月 前