Espresso点击菜单项

时间:2015-11-27 22:54:28

标签: java android testing android-actionbar android-espresso

我在操作栏中有一个菜单,我通过以下方式创建:

@Override
public boolean onCreateOptionsMenu(Menu menu) {

    menu.add(Menu.NONE, 98,Menu.NONE,R.string.filter).setIcon(R.drawable.ic_filter_list_white_48dp).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
    menu.add(Menu.NONE, 99,Menu.NONE,R.string.add).setIcon(R.drawable.ic_add_white_48dp).setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);


    getMenuInflater().inflate(R.menu.menu_main, menu);

    return true;
}

和menu_main.xml如下所示:

<menu xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    tools:context=".MainActivity">
    <item
        android:id="@+id/action_settings"
        android:title="@string/action_settings"
        android:orderInCategory="100"
        app:showAsAction="never"
        android:icon="@drawable/ic_settings_white_48dp"/>
</menu>

在Espresso中测试时,我想点击“添加”图标(menuId 99)。我试过了

@Test
public void testAdd() {
openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());
    onView(withText(R.string.add)).perform(click());
}

但是这会因NoMatchingViewException而失败。 (设置项,直接在xml中定义,我可以使用相同的代码单击。)

这适用于targetSdkVersion 23和AppCompatActivity。工具栏的相关行是:

Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
if( getSupportActionBar() != null ) {
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}

和tool_bar.xml看起来像:

<?xml version="1.0" encoding="utf-8"?>
<android.support.v7.widget.Toolbar     xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="wrap_content"
    android:theme="@style/ThemeOverlay.AppCompat.Dark"
    android:background="@color/ColorPrimary"
    android:elevation="4dp"
    tools:ignore="UnusedAttribute">
</android.support.v7.widget.Toolbar>

7 个答案:

答案 0 :(得分:36)

更新:我没有看到该行的最后一行,忽略了我以前的回复,我试图快速修复它并且我做错了。我真的不知道答案。

  // Click on the icon - we can find it by the r.Id.
  onView(withId(R.id.action_save))
    .perform(click());

您的问题由Espresso团队解释here

  

匹配可见图标:

  // Open the overflow menu OR open the options menu,
  // depending on if the device has a hardware or software overflow menu button.
  openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext());

  // Click the item.
  onView(withText("World"))
    .perform(click());
  

点击溢出菜单中的项目有点棘手   正常操作栏,因为某些设备有硬件溢出菜单按钮   (他们将打开选项菜单中的溢出项目)和一些   设备有一个软件溢出菜单按钮(它们将打开正常   溢出菜单)。幸运的是,Espresso为我们处理这个问题。

withId

所以我理解两种选择都是正确的,但取决于你的具体情况。如果你测试一个按钮,你通常知道那时它是否可见。

在您的情况下,按钮是可见的,因为有空间,使用import static android.support.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu; @Test public void testClickInsertItem() { openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext()); onView(withId(R.id.action_insert)).perform(click()); } {{1}}是正确的:

{{1}}

here对于溢出项也是正确的:

  

是的,这就是Espresso的工作原理。这里的问题是,在   Android,表示菜单项的View没有ID   菜单项。因此onView(withId(X))无法找到View。我不   有一个比使用withText()更好的建议。如果你有   具有相同文本的多个视图,使用层次结构进行区分   的工作原理。

现在我的问题是当你在不同的设备上进行测试时你该怎么办,而你却不知道什么时候会有一个项目的空间。我不知道答案,也许两者都结合起来。

答案 1 :(得分:3)

您可以使用此方法单击菜单项。首先使用此代码单击菜单按钮

openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext());

然后根据文本执行单击菜单项。使用&#34; MenuItemName&#34;

放置菜单项名称。
onView(withText("MenuItemName")).perform(click());

答案 2 :(得分:2)

这是我的解决方案,涵盖所有三种情况:硬件菜单按钮,溢出菜单,仅图标:

    try {
        openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());
    } catch (Exception e) {
        //This is normal. Maybe we dont have overflow menu.
    }
    onView(anyOf(withText(R.string.<your label for the menu item>), withId(R.id.<id of the menu item>))).perform(click());

答案 3 :(得分:1)

Espresso.openContextualActionModeOverflowMenu() 

是唯一适用于我的三星Note 3的选项。openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext());会尝试失败而不会出现任何错误

答案 4 :(得分:1)

使用此选项匹配菜单项的描述文本:

onView(withContentDescription(R.string.add)).perform(click());

然后你不必匹配(不存在的)ID,也不必匹配可绘制的图标。

此外,如果您需要确保扩展菜单,请记得使用the Espresso documentation中的此代码段:

// Open the overflow menu OR open the options menu,
// depending on if the device has a hardware or software overflow menu button.
openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext());

答案 5 :(得分:1)

不要受苦很多。让我们简化

onView(withId(98)).perform(click());

这将帮助您执行点击添加

答案 6 :(得分:0)

工具栏不是actionBar,不需要调用:

openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());

如果你这样做,那肯定你的项目不会在那里找到(它不在ActionBar中),而且ToolBar属于“普通视图”。