Java 浓缩咖啡点击菜单项

Java 浓缩咖啡点击菜单项,java,android,testing,android-actionbar,android-espresso,Java,Android,Testing,Android Actionbar,Android Espresso,我在actionbar中有一个菜单,通过以下方式创建: @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(

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

@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;
}
菜单_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>
<?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>
但这失败了,出现了一个NoMatchingViewException。(设置项是在xml中定义的,我可以用相同的代码直接单击它。)


这是针对targetSdkVersion 23和AppCompative的。工具栏的相关行包括:

Toolbar toolbar = (Toolbar) findViewById(R.id.tool_bar);
setSupportActionBar(toolbar);
if( getSupportActionBar() != null ) {
    getSupportActionBar().setDisplayHomeAsUpEnabled(true);
}
tool_bar.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>
<?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>

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

...setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
您的问题由浓缩咖啡团队解释:

匹配可见图标:

点击溢出菜单中的项目对于用户来说有点棘手 正常操作栏,因为某些设备具有硬件溢出菜单按钮 (它们将打开选项菜单中的溢出项)和一些 设备有一个软件溢出菜单按钮(它们将打开一个正常的 溢出菜单)。幸运的是,浓缩咖啡帮我们解决了这个问题

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

在您的情况下,按钮是可见的,因为有空间,并且正确地使用
with id
如下:

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

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


现在我的问题是,当你在不同的设备上进行测试时,你不知道什么时候会有空间放置一个项目。我不知道答案,可能是两种解决方案的结合。

工具栏不是操作栏,不需要调用:

openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());

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

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

openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext());
然后根据文本执行单击菜单项。将菜单项名称替换为“MenuItemName”


是我的三星Note 3唯一有效的选择。这
openActionBarOverFlowerOptions菜单(getInstrumentation().getTargetContext())
将尝试并没有任何错误地失败

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

    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());
试试看{
OpenActionBarOverflowerOptions菜单(InstrumentationRegistry.getTargetContext());
}捕获(例外e){
//这是正常的。也许我们没有溢出菜单。
}
onView(任意一个(带文本(R.string.),带id(R.id.)))。执行(单击());

使用此选项匹配菜单项的说明文本:

onView(withContentDescription(R.string.add)).perform(click());
然后,您不必在(不存在的)ID上匹配,也不必在可绘制图标上匹配

此外,如果需要确保菜单已展开,请记住使用中的此代码段:

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

不要太痛苦。让我们简化一下

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

这将帮助您执行单击添加

您使用的是什么
targetSdkVersion
、操作栏和设备/模拟器?。请参阅OpenActionBarOverflowerOptionsMenu()实现(Espresso类),这取决于这些因素。我需要对此进行调查,但根据我使用的emulator.targetSdkVersion 23和AppCompatActivity的不同,存在一些问题。我在上面添加了工具栏代码。当将文本与“withText(R.string.add)”匹配时会不会出现问题,因为实际文本不可见,但只有图标(R.drawable.ic_add_white_48dp)可见?这是在Sony Xperia SP(真实设备,而不是模拟器)上。这不是一个解决方案,但我注意到“onView(withId(99)).perform(click());”可以工作,尽管我记得在某个地方读到过,那些“菜单Id”和“视图Id”不一样……谢谢。因此,无法使用“withText()”匹配可见图标?如果可能的话,我希望尽量避免使用“withId()”,因为据我所知,测试应该模仿用户的动作,人类会寻找文本/图标,而不是(看不见的)id。我不知道,等待更好的回答,我回答,因为我认为这与我评论你的问题相同。如果没有人回答,我会更新它,我会找到更好的答案。我从来没有在房间里表演,我也在学浓缩咖啡。我知道这一点。但我更喜欢匹配“withText()”。另请参阅我对albodelu回答的评论。With Text不适合这种情况,因为浓缩咖啡基本上可以找到屏幕上显示的文本。但是,我们使用的图标没有任何文本。我们无法使用Text()执行操作。这是所有withText()不适用的情况下的最佳解决方案!它也适用于仅图标项目(app:showAsAction=“always”)。只需添加

    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());
onView(withContentDescription(R.string.add)).perform(click());
// 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());
onView(withId(98)).perform(click());