Android 检查 Espresso 是否显示对话框

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21045509/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-20 03:53:58  来源:igfitidea点击:

Check if a dialog is displayed with Espresso

androidandroid-espresso

提问by Serj Lotutovici

I'm trying to write some tests with the new android-test-kit (Espresso). But I can't find any information on how tocheck if a dialog is displayed and perform some actions on it (like clicking the positive and negative buttons, e.t.c.). Note that a dialog may be also displayed by a WebView, not by the application it self.

我正在尝试使用新的android-test-kit (Espresso)编写一些测试。但是我找不到有关如何检查对话框是否显示并对其执行某些操作(例如单击正面和负面按钮等)的任何信息。请注意,对话框也可能由 a 显示WebView,而不是由应用程序本身显示。

Any help would be appreciated. I just need a link, or some example code for the basics:

任何帮助,将不胜感激。我只需要一个链接,或者一些基本的示例代码:

  1. Check if a dialog appears
  2. Perform clicks on dialog buttons
  3. Interact with the dialog's inner view (if it's a custom view)
  4. Preform clicks outside the dialog, and check if it's displaying or not (for example if setCancelable(false)was called on the dialog builder and we want to check that)
  1. 检查是否出现对话框
  2. 单击对话框按钮
  3. 与对话框的内部视图交互(如果它是自定义视图)
  4. Preform 在对话框外点击,并检查它是否显示(例如,如果setCancelable(false)在对话框构建器上调用并且我们想要检查它)

Thank you in advice!

谢谢指教!

回答by denys

  1. To verify if dialog appears you can simply check if View with a text that present inside the dialog is shown:

    onView(withText("dialogText")).check(matches(isDisplayed()));
    

    or, based on text with id

    onView(withId(R.id.myDialogTextId)).check(matches(allOf(withText(myDialogText), isDisplayed()));
    
  2. To click on dialogs button do this (button1 - OK, button2 - Cancel):

    onView(withId(android.R.id.button1)).perform(click());
    

    UPDATE

  3. I think is possible since Espresso has multi window support.
  4. Not sure about clicking outside the custom dialog view but for checking if it is displaying or not you have to create your custom matcher and check inside it.
  1. 要验证对话框是否出现,您可以简单地检查是否显示了对话框内的文本:

    onView(withText("dialogText")).check(matches(isDisplayed()));
    

    或者,基于带有 id 的文本

    onView(withId(R.id.myDialogTextId)).check(matches(allOf(withText(myDialogText), isDisplayed()));
    
  2. 要单击对话框按钮,请执行此操作(按钮 1 - 确定,按钮 2 - 取消):

    onView(withId(android.R.id.button1)).perform(click());
    

    更新

  3. 我认为这是可能的,因为 Espresso 具有多窗口支持
  4. 不确定是否在自定义对话框视图外单击,但要检查它是否显示,您必须创建自定义匹配器并在其中检查。

回答by kiruwka

I currently use this and it seems to work fine.

我目前使用它,它似乎工作正常。

onView(withText(R.string.my_title))
    .inRoot(isDialog()) // <---
    .check(matches(isDisplayed()));

回答by Luiz Augusto

If you have an AlertDialog like that:

如果您有这样的 AlertDialog:

enter image description here

在此处输入图片说明

You can check if the components are displayed:

您可以检查组件是否显示:

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

and perform an action:

并执行一个动作:

onView(withId(android.R.id.button3)).perform(click());

回答by Diana Farin

Just in case anyone stumbles across this question like I did. All the answers will only work for dialogs WITH dialog buttons. Do not try and use this for progress dialogs without user interaction. Espresso keeps waiting for the app to enter an idle state. As long as the progress dialog is visible the app is not idle.

以防万一有人像我一样偶然发现这个问题。所有答案仅适用于带有对话框按钮的对话框。不要尝试在没有用户交互的情况下将其用于进度对话框。Espresso 一直在等待应用程序进入空闲状态。只要进度对话框可见,应用程序就不会空闲。

回答by AutonomousApps

To answer question 4, which the accepted answer does not, I modified the following code, which I found here on Stack Overflow (link) for testing whether a Toast was displayed.

为了回答已接受的答案没有的问题 4,我修改了以下代码,我在 Stack Overflow(链接)上找到了该代码,用于测试是否显示了 Toast。

@NonNull
public static ViewInteraction getRootView(@NonNull Activity activity, @IdRes int id) {
    return onView(withId(id)).inRoot(withDecorView(not(is(activity.getWindow().getDecorView()))));
}

The idpassed in is the id of a Viewcurrently displayed in your dialog. You could also write the method like so:

id传入是一个标识View当前显示的你的对话框英寸 您也可以像这样编写方法:

@NonNull
public static ViewInteraction getRootView(@NonNull Activity activity, @NonNull String text) {
    return onView(withText(text)).inRoot(withDecorView(not(is(activity.getWindow().getDecorView()))));
}

And now it's looking for a Viewcontaining a particular text string.

现在它正在寻找一个View包含特定文本字符串的字符串。

Use it like so:

像这样使用它:

getRootView(getActivity(), R.id.text_id).perform(click());

回答by JaydeepW

The button Ids R.id.button1 and R.id.button2 are not going to be same across devices. The Ids may change with the OS versions.

按钮 ID R.id.button1 和 R.id.button2 在不同设备上不会相同。Id 可能会随操作系统版本而变化。

The correct way to achieve this is to use UIAutomator. Include UIAutomator dependency in your build.gradle

实现这一点的正确方法是使用 UIAutomator。在 build.gradle 中包含 UIAutomator 依赖项

// Set this dependency to build and run UI Automator tests
  androidTestCompile 'com.android.support.test.uiautomator:uiautomator-v18:2.1.2'

and use

并使用

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