如何使用Espresso来点击AlertDialog中的按钮

24

我想使用Espresso按下下面的按钮,但我不确定如何操作。我应该获取资源ID吗?或者如何为AlertDialog设置ID?

enter image description here

@RunWith(AndroidJUnit4.class)
public class ApplicationTest {

@Rule
public ActivityTestRule<LoadingActivity> mActivityRule =
        new ActivityTestRule<>(LoadingActivity.class);

@Test
public void loginClickMarker() {
//Doesn't work:
    onView(withText("GA NAAR INSTELLINGEN")).perform(click());
}
}

public class PopupDialog {

public static void showGPSIsDisabled(Context context, String msg, final PopupDialogCallback popupDialogCallback) {
    new AlertDialog.Builder(context)
            .setTitle(context.getString(R.string.location_turned_off))
            .setMessage(msg)
            .setPositiveButton(context.getString(R.string.go_to_settings), new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    dialog.dismiss();
                    popupDialogCallback.hasClicked();
                }
            }).show();
}
}

android.support.test.espresso.NoMatchingViewException: 找不到匹配的层次结构中的视图:文本为“GA NAAR INSTELLINGEN”。

我认为你可以使用withText()方法来代替按id匹配。 - jeprubio
onView(withText("GA NAAR INSTELLINGEN")).perform(click()); 无法正常工作。 - Jim Clermonts
6个回答

58
根据StackOverflow类似问题:使用Espresso检查对话框是否显示
你应该将你的代码改为:
onView(withText("GA NAAR INSTELLINGEN")).perform(click());

onView(withText("GA NAAR INSTELLINGEN"))
    .inRoot(isDialog())                 
    .check(matches(isDisplayed()))      
    .perform(click());  
            

如果它不能正常工作,就不要费心使用与Espresso另一个伟大的Google仪器测试称为uiatomator。
检查:http://qathread.blogspot.com/2015/05/espresso-uiautomator-perfect-tandem.html 示例代码:
// Initialize UiDevice instance
UiDevice uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation());

// Search for correct button in the dialog.
UiObject button = uiDevice.findObject(new UiSelector().text("GA NAAR INSTELLINGEN"));
if (button.exists() && button.isEnabled()) {
    button.click();
}

这对我来说没有 check() 方法也可以工作。 - Taslim Oseni

11

由于 inRoot(isDialog()) 看起来不能用于 DialogFragment,因此我目前使用这个解决方案:

enum class AlertDialogButton(@IdRes val resId: Int) {
    POSITIVE(android.R.id.button1),
    NEGATIVE(android.R.id.button2),
    NEUTRAL(android.R.id.button3)
}

fun clickOnButtonInAlertDialog(button: AlertDialogButton) {
    onView(withId(button.resId)).perform(click())
}

谢谢!isDialog()对我无效,但我能找到button1和button2。感谢您明确地写出不同按钮与其ID号码对应的方式。 - Zeek Aran

7
对于AlertDialog,每个按钮分配的id如下:
  • 积极的: android.R.id.button1
  • 消极的: android.R.id.button2
  • 中性的: android.R.id.button3
您可以在AlertController类的setupButtons()方法中自行检查。因此,您可以按以下方式执行单击操作: onView(withId(android.R.id.button1)).perform(click());

6
您可能需要像这样关闭软键盘:
        onView(withId(R.id.username))
                .perform(typeText("username"))
                .perform(closeSoftKeyboard())
        onView(withId(android.R.id.button1)).perform((click()))

此回答所述,更详细地解释了相关的IT技术问题。


我不知道这是否是一个新的事物,但是androidx.test.espresso.action.ViewActions有一个方法closeSoftKeyboard() - nasch
也不需要使用 perform() 包装 closeSoftKeyBoard() 的调用。 - Chisko

3
上次更新的好处是它允许你在每个测试前设置权限,这样你就不必再点击对话框(这会大大加快测试速度!)。
使用以下规则(例如,对于位置/存储...请将其替换为你需要的权限)。
@Rule
  public GrantPermissionRule runtimePermissionRule = GrantPermissionRule.grant(
      ACCESS_FINE_LOCATION, READ_EXTERNAL_STORAGE);

3

AlertController类中,Android操作系统为AlertDialog按钮设置了id。请检查setupButtons方法。例如,在撰写本文时,正面按钮的ID为16908313。因此,您可以编写以下代码:

onView(withId(DIALOG_POSITIVE_BUTTON_ID)).check(matches(isDisplayed()));

DIALOG_POSITIVE_BUTTON_ID = 16908313。

同样适用于负面按钮。


1
对我来说,这是最好的解决方案。 - Safety

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接