Проверьте, отображается ли диалог с эспрессо
Я пытаюсь написать несколько тестов с новым набором android-test-kit (Espresso). Но я не могу найти какую-либо информацию о том, как проверить, отображается ли диалоговое окно, и выполнить над ним какие-либо действия (например, нажав на положительные и отрицательные кнопки и т. Д.). Обратите внимание, что диалог может также отображаться WebView
, а не приложение само по себе.
Любая помощь будет оценена. Мне просто нужна ссылка или пример кода для основ:
- Проверьте, появляется ли диалоговое окно
- Выполнять нажатия на кнопки диалога
- Взаимодействовать с внутренним видом диалога (если это пользовательский вид)
- Преформа щелкает за пределами диалогового окна и проверяет, отображается ли оно или нет (например, если
setCancelable(false)
был вызван на диалоге, и мы хотим проверить это)
Спасибо за совет!
7 ответов
Чтобы проверить, появляется ли диалоговое окно, вы можете просто проверить, отображается ли View с текстом, который присутствует внутри диалога:
onView(withText("dialogText")).check(matches(isDisplayed()));
или, на основе текста с идентификатором
onView(withId(R.id.myDialogTextId)).check(matches(allOf(withText(myDialogText), isDisplayed()));
Чтобы нажать кнопку диалога, сделайте это (button1 - OK, button2 - Cancel):
onView(withId(android.R.id.button1)).perform(click());
ОБНОВИТЬ
- Я думаю, что это возможно, так как Espresso имеет многооконную поддержку.
- Не уверен, что нажмете за пределами пользовательского диалогового окна, но для проверки, отображается ли он или нет, вам нужно создать свой собственный сопоставитель и проверить внутри него.
Я в настоящее время использую это, и, кажется, работает нормально.
onView(withText(R.string.my_title))
.inRoot(isDialog()) // <---
.check(matches(isDisplayed()));
Если у вас AlertDialog вот так:
Вы можете проверить, отображаются ли компоненты:
int titleId = mActivityTestRule.getActivity().getResources()
.getIdentifier( "alertTitle", "id", "android" );
onView(withId(titleId))
.inRoot(isDialog())
.check(matches(withText(R.string.my_title)))
.check(matches(isDisplayed()));
onView(withId(android.R.id.text1))
.inRoot(isDialog())
.check(matches(withText(R.string.my_message)))
.check(matches(isDisplayed()));
onView(withId(android.R.id.button2))
.inRoot(isDialog())
.check(matches(withText(android.R.string.no)))
.check(matches(isDisplayed()));
onView(withId(android.R.id.button3))
.inRoot(isDialog())
.check(matches(withText(android.R.string.yes)))
.check(matches(isDisplayed()));
и выполнить действие:
onView(withId(android.R.id.button3)).perform(click());
На всякий случай кто-нибудь наткнется на этот вопрос, как я. Все ответы будут работать только для диалогов с диалоговыми кнопками. Не пытайтесь использовать это для диалогов прогресса без взаимодействия с пользователем. Эспрессо продолжает ждать, пока приложение перейдет в режим ожидания. Пока диалог прогресса виден, приложение не бездействует.
Чтобы ответить на вопрос 4, на который нет принятого ответа, я изменил следующий код, который я нашел здесь в переполнении стека ( ссылка), чтобы проверить, отображался ли тост.
@NonNull
public static ViewInteraction getRootView(@NonNull Activity activity, @IdRes int id) {
return onView(withId(id)).inRoot(withDecorView(not(is(activity.getWindow().getDecorView()))));
}
id
передано это идентификатор View
в настоящее время отображается в вашем диалоге. Вы также можете написать метод так:
@NonNull
public static ViewInteraction getRootView(@NonNull Activity activity, @NonNull String text) {
return onView(withText(text)).inRoot(withDecorView(not(is(activity.getWindow().getDecorView()))));
}
И теперь он ищет View
содержащий определенную текстовую строку.
Используйте это так:
getRootView(getActivity(), R.id.text_id).perform(click());
Если вы не хотите проверять конкретную строку в диалоговом окне, вы можете использовать hasWindowFocus()
, нравится:
// Kotlin, with ActivityScenarioRule
activityScenarioRule.scenario.onActivity { activity ->
val dialogIsDisplayed = !activity.hasWindowFocus()
}
// Kotlin, with ActivityTestRule
val dialogIsDisplayed = !activityTestRule.activity.hasWindowFocus()
// Java 7, with ActivityScenarioRule
activityScenarioRule.getScenario().onActivity(new ActivityScenario.ActivityAction<MyActivity>() {
@Override
public void perform(MyActivity activity) {
boolean dialogIsDisplayed = !activity.hasWindowFocus();
}
});
// Java, with ActivityTestRule
boolean dialogIsDisplayed = !activityTestRule.getActivity().hasWindowFocus();
Источники:
Идентификаторы кнопок R.id.button1 и R.id.button2 не будут одинаковыми на разных устройствах. Идентификаторы могут меняться в зависимости от версии ОС.
Правильный способ добиться этого - использовать UIAutomator. Включите зависимость UIAutomator в ваш build.gradle
// Set this dependency to build and run UI Automator tests
androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'
и использовать
// Initialize UiDevice instance
UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());
// Search for correct button in the dialog.
UiObject button = uiDevice.findObject(new UiSelector().text("ButtonText"));
if (button.exists() && button.isEnabled()) {
button.click();
}