Тестирование Android: ожидалось, что корень иерархии представлений будет иметь фокус окна

При тестировании 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()));

но ни один из них не работает ... Подскажите пожалуйста, как получить рут ралаванта?


person Kimmy    schedule 12.09.2016    source источник


Ответы (6)


Эта ошибка может произойти, когда отображается системное диалоговое окно - например, «Выключено» или «К сожалению, программа запуска остановлена ​​(сбой фонового приложения) - и вы пытаетесь запустить модульный тест Espresso, пока отображается это диалоговое окно.

Диалоговое окно системы Android: К сожалению, программа запуска остановлена.

Изображение предоставлено: в эмуляторе Android 4.0 всегда есть сбой лаунчера?

Вы можете обойти это в коде, закрыв системный диалог перед запуском теста:

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) или работает медленно, и появляется системное диалоговое окно с сообщением "Application Isn't Responding. Do you want to close it? [Wait] [OK]":

Диалоговое окно системы Android: программа запуска не отвечает. Вы хотите закрыть ее? Подождите, ОК

Изображение предоставлено: https://engineering.linkedin.com/blog/2016/08/introduction-and-open-sourcing-test-butler--reliable-android-test

Если вы попытаетесь запустить тест эспрессо, пока отображается это диалоговое окно, все они потерпят неудачу и покажут ошибку Ожидается корень ... Нет простого способа закрыть это диалоговое окно программно. Эспрессо не может нажимать эти кнопки по причинам, описанным здесь: Закрыть диалоговое окно с предупреждением в Android Espresso Тест. Однако один из способов - использовать UIAutomator для нажатия кнопки ожидания в диалоговом окне непосредственно перед запуском теста:

приложение / build.gradle

dependencies {
    ...
    androidTestImplementation "androidx.test.uiautomator:uiautomator:2.2.0"
}

ActivityUiTest.kt

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()
        }
    }
}

ActivityUiTest.java

@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();
    }
}

В качестве альтернативы вы можете использовать adb в командной строке для отправки касания экрана или нажмите клавиши, чтобы закрыть его. Например:

# 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

or

# 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

Дополнительная информация:

person Mr-IDE    schedule 15.01.2019
comment
Спасибо, это именно то, с чем я столкнулся - person Segun Wahaab; 24.01.2020

У меня была такая же ошибка, когда я использовал Spinner внутри DialogFragment. Это единственный код, который у меня работал:

onView(withText(containsString("A4"))).inRoot(isPlatformPopup()).check(matches(isDisplayed()));
person StefanTo    schedule 13.10.2016
comment
Это решило мою проблему при использовании Spinner внутри AlertDialog. - person Dielson Sales; 22.05.2017

У меня была аналогичная проблема, когда всплывающее диалоговое окно содержало элементы счетчика (раскрывающийся список), мой щелчок не мог выполнить ни один из элементов счетчика и получил ту же ошибку. Я нашел решение, используя метод onData () с RootMatchers:

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

Обратите внимание, что значение индекса в atPosition () - это значение индекса элемента из списка счетчика.

person Jamil Rahman    schedule 24.07.2018

На всякий случай, если это случится с чьей-либо сборкой Трэвиса (с точно таким же логом). Проверьте это.

Была точно такая же проблема и решена путем создания avd с более низкой целевой версией (19).

Что я пробовал и не сработало:

  • Добавление метода 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

to

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

отлично решите вопрос.

person Jing Li    schedule 22.11.2016

просто обновите инструменты сборки в 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 &
person denis_lor    schedule 26.07.2017

Возможно, проблема недавно обновлена, но с новой версией Android.
AndroidX Test: 1.3.0
Espresso: 3.3.0
Android OS: Android 11 (API 30)
См. https://github.com/android/android-test/issues/751

person t0m    schedule 12.01.2021