Android isDialog()与Espresso中的对话框片段不匹配

Android isDialog()与Espresso中的对话框片段不匹配,android,android-studio,android-testing,android-espresso,Android,Android Studio,Android Testing,Android Espresso,我有一套使用Cucumber JVM和Espresso运行的Android UI测试。然而,我面临着与对话片段交互的问题 另一个片段在顶部创建一个对话框片段,其中包含一些视图元素。当我尝试检查/交互这些时,Espresso似乎在视图层次结构中根本找不到它们。它在错误消息中显示的视图层次结构是底层片段的层次结构,而不是对话框片段的层次结构,这使我认为它选择了错误的根视图 为了解决这个问题,我在语句中添加了inRoot(isDialog()): onView(withText("Ok")).inRo

我有一套使用Cucumber JVM和Espresso运行的Android UI测试。然而,我面临着与对话片段交互的问题

另一个片段在顶部创建一个对话框片段,其中包含一些视图元素。当我尝试检查/交互这些时,Espresso似乎在视图层次结构中根本找不到它们。它在错误消息中显示的视图层次结构是底层片段的层次结构,而不是对话框片段的层次结构,这使我认为它选择了错误的根视图

为了解决这个问题,我在语句中添加了inRoot(isDialog()):

onView(withText("Ok")).inRoot(isDialog()).check(matches(isDisplayed()));
  onView(withText("Ok")).inRoot(isDialog()).check(matches(isDisplayed()));
这将导致以下错误消息:

android.support.test.espresso.NoMatchingRootException: Matcher 'is dialog' did not match any of the following roots: [Root{application-window-token=android.view.ViewRootImpl$W@f99cfec, window-token=android.view.ViewRootImpl$W@f99cfec, has-window-focus=true, layout-params-type=1, layout-params-string=WM.LayoutParams{(0,0)(fillxfill) sim=#20 ty=1 fl=#1810100 wanim=0x10303e5 needsMenuKey=2}, decor-view-string=DecorView{id=-1, visibility=VISIBLE, width=1080, height=1794, has-focus=true, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}}, Root{application-window-token=android.view.ViewRootImpl$W@e5f9fb5, window-token=android.view.ViewRootImpl$W@e5f9fb5, has-window-focus=false, layout-params-type=1, layout-params-string=WM.LayoutParams{(0,0)(fillxfill) sim=#20 ty=1 fl=#1810100 wanim=0x10303e5 needsMenuKey=2}, decor-view-string=DecorView{id=-1, visibility=INVISIBLE, width=1080, height=1794, has-focus=true, has-focusable=false, has-window-focus=false, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}}, Root{application-window-token=android.view.ViewRootImpl$W@c5e564a, window-token=android.view.ViewRootImpl$W@c5e564a, has-window-focus=false, layout-params-type=1, layout-params-string=WM.LayoutParams{(0,0)(fillxfill) ty=1 fl=#1810100 wanim=0x10303e5 needsMenuKey=2}, decor-view-string=DecorView{id=-1, visibility=INVISIBLE, width=1080, height=1794, has-focus=true, has-focusable=false, has-window-focus=false, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}}, Root{application-window-token=android.view.ViewRootImpl$W@9b179bb, window-token=android.view.ViewRootImpl$W@9b179bb, has-window-focus=false, layout-params-type=1, layout-params-string=WM.LayoutParams{(0,0)(fillxfill) ty=1 fl=#1810100 wanim=0x10303e5 needsMenuKey=2}, decor-view-string=DecorView{id=-1, visibility=INVISIBLE, width=1080, height=1794, has-focus=false, has-focusable=false, has-window-focus=false, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=1}}]
at dalvik.system.VMStack.getThreadStackTrace(Native Method)
at java.lang.Thread.getStackTrace(Thread.java:580)
用于创建对话框的代码:

public class ServiceItemFragment extends Fragment {
    ...
    public void showASampleDialog() {
        DialogFragment newFragment = SampleDialogFragment.newInstance(
                R.string.dialog_title);
        newFragment.show(getFragmentManager(), "dialog");
    }
}
对话框片段的代码:

public class SampleDialogFragment extends DialogFragment {

    public static SampleDialogFragment newInstance(int title) {
        SampleDialogFragment frag = new SampleDialogFragment();
        Bundle args = new Bundle();
        args.putInt("title", title);
        frag.setArguments(args);
        return frag;
    }

    @Override
    public Dialog onCreateDialog(Bundle savedInstanceState) {
        int title = getArguments().getInt("title");

        return new AlertDialog.Builder(getActivity())
                .setTitle(title)
                .setPositiveButton("Ok",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int whichButton) {
                                Log.i(getClass().getSimpleName(), "Positive click");
                            }
                        }
                )
                .setNegativeButton("Cancel",
                        new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialog, int whichButton) {
                                Log.i(getClass().getSimpleName(), "Negative click");
                            }
                        }
                )
                .create();
    }
}
为了解决这个问题,我在语句中添加了inRoot(isDialog()):

onView(withText("Ok")).inRoot(isDialog()).check(matches(isDisplayed()));
  onView(withText("Ok")).inRoot(isDialog()).check(matches(isDisplayed()));
如果您使用的是
AlertDialog
,而不是
DialogFragment

为此,最佳解决方案是您的实际解决方案,我的意思是:

UIAutomator: UiDevice device = UiDevice.getInstance(getInstrumentation());
UiObject uiObject = device.findObject(new UiSelector().text("Ok"));
try {
    uiObject.click();
} catch (UiObjectNotFoundException e) {
    throw new RuntimeException("UI Object not found", e);
}
类似的帖子和答案可以在这里找到:

还可以尝试ommit
inRoot()
matcher,并尽可能简单地编写测试,如:

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

这可能也很有用:

您还可以匹配不是当前活动的任何根:

onView(带文本(“Ok”)).inRoot(带DecorView)(不是(is(testRule.getActivity().getWindow().getDecorView()))))。检查(匹配项(isDisplayed())


它也可能是设备动画问题。请确保在设备的开发设置中禁用它。

目前我正在使用UIAutomator解决此问题:UiDevice device=UiDevice.getInstance(getInstrumentation());UiObject UiObject=device.findObject(new UiSelector().text(“确定”);尝试{UiObject.click();}catch(UiObjectNotFoundException e){抛出新的RuntimeException(“未找到UI对象”,e);}该选项似乎与其他根目录匹配,因为测试暂停,并且由于不活动的rootview而在稍后终止。我还禁用了开发人员设置中的动画。好的,我将保留该解决方案。如果Espresso根本无法使用DialogFragments,则有点令人失望。