Espresso 点击菜单项
Espresso click menu item
我在操作栏中有一个菜单,它是通过以下方式创建的:
@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 中进行测试时,我想单击 "add" 图标(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>
更新:我没有看到最后一行,忽略我之前的回复,我试图快速修复它但我做错了。我真的不知道答案。
...setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
Espresso 团队 here 解释了您的问题:
Matching visible icons:
// Click on the icon - we can find it by the r.Id.
onView(withId(R.id.action_save))
.perform(click());
Clicking on items in the overflow menu is a bit trickier for the
normal action bar as some devices have a hardware overflow menu button
(they will open the overflowing items in an options menu) and some
devices have a software overflow menu button (they will open a normal
overflow menu). Luckily, Espresso handles that for us.
// 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());
所以我知道这两种选择都是正确的,但取决于您的具体情况。如果您测试一个按钮,您通常会知道它在那一刻是否可见。
在你的例子中,按钮是可见的,因为有空间,使用 withId
是正确的,比如 :
import static android.support.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu;
@Test
public void testClickInsertItem() {
openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());
onView(withId(R.id.action_insert)).perform(click());
}
但是this对于溢出项也是正确的:
Yes, this is how it works in Espresso. The problem here is, that in
Android, the View representing the menu item doesn't have the ID of
the menu item. So onView(withId(X)) just fails to find a View. I don't
have a better recommendation than just using withText(). If you have
multiple views with the same text, using hierarchy for distinction
works.
现在我的问题是,当您在不同的设备上进行测试并且您不知道什么时候可以容纳某个项目时该怎么办。我不知道响应,也许结合两种解决方案。
工具栏不是actionBar,不需要调用:
openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());
如果你这样做,那肯定不会在那里找到你的项目(它不在 ActionBar 中)并且工具栏属于 "normal view"。
您可以使用此方法点击菜单项。首先使用此代码单击菜单按钮
openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext());
然后根据text.Replace你的菜单项名称执行点击菜单项"MenuItemName"
onView(withText("MenuItemName")).perform(click());
Espresso.openContextualActionModeOverflowMenu()
是唯一适用于我的三星 Note 3 的选项。这个 openActionBarOverflowOrOptionsMenu(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());
使用它来匹配菜单项的描述文本:
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());
不要太痛苦。让我们简单点。
onView(withId(98)).perform(click());
这将帮助您执行点击添加
我在操作栏中有一个菜单,它是通过以下方式创建的:
@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 中进行测试时,我想单击 "add" 图标(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>
更新:我没有看到最后一行,忽略我之前的回复,我试图快速修复它但我做错了。我真的不知道答案。
...setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)
Espresso 团队 here 解释了您的问题:
Matching visible icons:
// Click on the icon - we can find it by the r.Id.
onView(withId(R.id.action_save))
.perform(click());
Clicking on items in the overflow menu is a bit trickier for the normal action bar as some devices have a hardware overflow menu button (they will open the overflowing items in an options menu) and some devices have a software overflow menu button (they will open a normal overflow menu). Luckily, Espresso handles that for us.
// 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());
所以我知道这两种选择都是正确的,但取决于您的具体情况。如果您测试一个按钮,您通常会知道它在那一刻是否可见。
在你的例子中,按钮是可见的,因为有空间,使用 withId
是正确的,比如
import static android.support.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu;
@Test
public void testClickInsertItem() {
openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());
onView(withId(R.id.action_insert)).perform(click());
}
但是this对于溢出项也是正确的:
Yes, this is how it works in Espresso. The problem here is, that in Android, the View representing the menu item doesn't have the ID of the menu item. So onView(withId(X)) just fails to find a View. I don't have a better recommendation than just using withText(). If you have multiple views with the same text, using hierarchy for distinction works.
现在我的问题是,当您在不同的设备上进行测试并且您不知道什么时候可以容纳某个项目时该怎么办。我不知道响应,也许结合两种解决方案。
工具栏不是actionBar,不需要调用:
openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());
如果你这样做,那肯定不会在那里找到你的项目(它不在 ActionBar 中)并且工具栏属于 "normal view"。
您可以使用此方法点击菜单项。首先使用此代码单击菜单按钮
openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext());
然后根据text.Replace你的菜单项名称执行点击菜单项"MenuItemName"
onView(withText("MenuItemName")).perform(click());
Espresso.openContextualActionModeOverflowMenu()
是唯一适用于我的三星 Note 3 的选项。这个 openActionBarOverflowOrOptionsMenu(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());
使用它来匹配菜单项的描述文本:
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());
不要太痛苦。让我们简单点。
onView(withId(98)).perform(click());
这将帮助您执行点击添加