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

时间:2016-09-12 19:21:16

标签: android automated-tests uiautomator android-espresso

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

我试过了

onData(allOf(is(instanceOf(String.class)),containsString("A4"))).inRoot(isPlatformPopup()).perform(click());

onView(withText(containsString("A4"))).inRoot(isFocusable()).check(matches(isDisplayed()));

onView(withText(containsString("A4"))).inRoot(withDecorView(not(getActivity().getWindow().getDecorView()))).check(matches(isDisplayed()));

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

6 个答案:

答案 0 :(得分:6)

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

onView(withText(containsString("A4"))).inRoot(isPlatformPopup()).check(matches(isDisplayed()));

答案 1 :(得分:1)

万一发生在任何人的Travis构建中(具有完全相同的日志)。请检查this

有完全相同的问题,并通过创建具有较低目标版本的avd(19)来解决。

我尝试过但没有工作的事情:

  • 在UI测试中添加unlockScreen() @Before方法。

  • 添加/删除adb shell input keyevent 82 &

  • 删除不同的emulator命令选项-no-skin-no-audio-no-window。现在我-no-window就可以了。

最后,改变 从

echo no | android create avd --force -n test -t android-24 --abi armeabi-v7a

echo no | android create avd --force -n test -t android-19 --abi armeabi-v7a

完美地解决了这个问题。

答案 2 :(得分:0)

只需更新travis.yml中的构建工具:

  • 在此文件.travis.yml中:您应该拥有此before_install: - echo yes | android update sdk --all --filter build-tools-26.0.1 --no-ui --force
  • 同样在.travis.yml
script: echo no | android create avd --force -n test -t android-22
--abi armeabi-v7a emulator -avd test -no-audio -no-window & 
android-wait-for-emulator 
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 &
adb shell input keyevent 82 &

答案 3 :(得分:0)

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

onData(anything()).inRoot(RootMatchers.isPlatformPopup()).atPosition(1).perform(click());

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

答案 4 :(得分:0)

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

Android system dialog: Unfortunately, Launcher has stopped.

图片来源:http://zte-iqorsupport.custhelp.com/app/answers/detail/a_id/4597/~/phone-is-getting-an-error-message%3A-unfortunately-launcher-has-stopped

您可以通过在运行测试之前关闭系统对话框来解决此问题:

MyActivity activityUnderTest = activityTestRule.getActivity();
activityUnderTest.sendBroadcast(new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS));

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

adb shell am broadcast -a android.intent.action.CLOSE_SYSTEM_DIALOGS

另一个原因是当后台应用程序冻结(ANR)或运行缓慢时,系统对话框显示“应用程序无响应。您要关闭它吗?[等待] [确定]” :

Android system dialog: Launcher isn't Responding. Do you want to close it? Wait, OK

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

如果您在此对话框可见的情况下尝试运行Espresso测试,它们将全部失败并显示错误。

无法以编程方式关闭此对话框。但是您可以在命令行上使用adb发送screen tapskey strokes来关闭它。例如:

# On a 320x480 screen, click at screen location [x=233,y=293] to tap an "OK" dialog button.
# Just in case there is a "Launcher isn't responding" system dialog.
adb shell input tap 233 293

# Send keystroke Arrow Right
sleep 3; adb shell input keyevent 22
# Send keystroke Arrow Right again
sleep 3; adb shell input keyevent 22
# Send keystroke Enter to press a button on the dialog
sleep 3; adb shell input keyevent 66

更多信息:

答案 5 :(得分:0)

也许是最新的问题,但与新的 Android 版本有关。
AndroidX 测试:1.3.0
浓缩咖啡:3.3.0
Android 操作系统:Android 11 (API 30)
https://github.com/android/android-test/issues/751