检查Espresso是否显示对话框

我试图用新的android-test-kit(Espresso)写一些testing。 但我找不到任何有关如何检查对话框的信息,并执行一些操作(如点击正面和负面的button等)。 请注意,对话框也可能由WebView显示,而不是由应用程序自行显示。

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

  1. 检查是否出现对话框
  2. 点击对话框button
  3. 与对话框的内部视图交互(如果是自定义视图)
  4. 瓶坯在对话框外单击,并检查是否显示(例如,如果在对话框构build器上调用了setCancelable(false) ,并且我们要检查)

谢谢你的build议!

  1. 要validation是否出现对话框,您可以简单地检查是否显示对话框中显示的文本的视图:

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

    或者,基于带有ID的文本

     onView(withId(R.id.myDialogTextId)).check(matches(allOf(withText(myDialogText), isDisplayed())); 
  2. 点击对话框button做这个(button1 – 确定,button2 – 取消):

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

    UPDATE

  3. 我认为是可能的,因为Espresso 有多窗口支持 。
  4. 不知道关于在自定义对话框视图之外单击,但为了检查是否显示,您必须创build自定义匹配器并在其中进行检查。

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

 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,我修改了下面的代码,我在Stack Overflow( 链接 )中find了用于testing是否显示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的ID。 你也可以这样写:

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

现在它正在寻找包含特定文本string的View

像这样使用它:

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

设备上的Ids R.id.button1和R.id.button2button不会相同。 Ids可能会随操作系统版本而改变。

达到此目的的正确方法是使用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(); } 

以防万一有人像我一样绊倒这个问题。 所有的答案只适用于与对话框button的对话框。 不要试图在没有用户交互的情况下将其用于进度对话框。 Espresso一直在等待应用程序进入闲置状态。 只要进度对话框可见,应用程序就不会闲置。