Java 浓缩咖啡点击菜单项
我在actionbar中有一个菜单,通过以下方式创建: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(
@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());