检查是否使用Espresso显示对话框


86

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

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

  1. 检查是否出现对话框
  2. 单击对话框按钮
  3. 与对话框的内部视图进行交互(如果是自定义视图)
  4. 瓶坯在对话框外单击,并检查其是否显示(例如,是否setCancelable(false)在对话框构建器中被调用,我们要检查)

谢谢指教!


对下面我的回答有任何反馈吗?
否认2014年

Answers:


123
  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. 不确定是否要在自定义对话框视图之外单击,但是要检查它是否显示,您必须创建自定义匹配器并在其中进行检查。

3
步骤1在ProgressDialog上对我不起作用。只是想验证对话框的标题和消息
Tim Boland 2014年

1
意式浓缩咖啡和静态进口食品有什么用?这些方法来自哪些类?为什么在堆栈溢出答案上使用静态导入?

2
@jvrodrigues每个Espresso教程都使用静态导入。我建议您只是习惯一下(尽管我了解这种挫败感)。这有助于:google.github.io/android-testing-support-library/docs
AutonomousApps

对于第4步,您可以调用“ pressBack();”来代替在对话框外单击。退出对话框。这等效于使用硬件后退按钮。
伊桑(Ethan)2016年

@denys项目已移动。似乎链接已死。
霓虹灯Warge '16

67

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

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

27

如果您有类似的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());

2
在我的案例中,该文本的ID为android.R.id.message,标题的隐藏ID为android.R.id.alertTitle
杰森·罗宾逊

2
如果您使用AppCompat支持库中的AlertDialog(或DialogFragment),请使用以下命令:int alertDialogTitleId = android.support.v7.appcompat.R.id.alertTitle;
Mr-IDE

3

为了回答问题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()))));
}

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

3

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

实现此目的的正确方法是使用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'

和使用

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

1
其实android.R.id.button1android.R.id.button2android.R.id.button3为“正”,“中性”和“负”,是全球性的符号可以被使用。如果您选择通过按钮的文本来选择按钮-完全没问题-您不需要UIAutomator,但是可以使用Espresso的按钮做同样的事情onView(withText("ButtonTest")).perform(click())
Thomas Keller

我将此解决方案与Robotium测试框架一起使用,并且能够轻松选择Android OS对话框按钮。节省了我很多时间。谢谢jaydeepw!

@ThomasKeller我过去曾经使用过button1,button2 id,当我在各种设备上运行它们时,我的测试失败了。显示的对话框是系统控件。不是您的控件/ UI。对于UI之外的任何内容,建议使用UIAutomator。
JaydeepW '16

而已。非常感谢。
1lb3r

3

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.