简体   繁体   English

Espresso点击菜单项

[英]Espresso click menu item

I have a menu in the actionbar which I create through: 我在操作栏中有一个菜单,我通过以下方式创建:

@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;
}

and menu_main.xml looks like: 和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>

When testing in Espresso I would like to click on the "add" icon (menuId 99). 在Espresso中测试时,我想点击“添加”图标(menuId 99)。 I tried 我试过了

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

but this fails with a NoMatchingViewException. 但是这会因NoMatchingViewException而失败。 ( The settings item, which is defined in the xml directly I can click with the same code. ) (设置项,直接在xml中定义,我可以使用相同的代码单击。)

That's for targetSdkVersion 23 and AppCompatActivity. 这是针对targetSdkVersion 23和AppCompatActivity的。 The relevant lines for the tool bar are: 工具栏的相关行是:

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

and tool_bar.xml looks like: 和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>

Update : I didn't see the final of the line, ignore my previous responses, I tried to fix it fast and I did wrong. 更新 :我没有看到最后一行,忽略我之前的回复,我试图快速解决它,我做错了。 I really didn't know the answer. 我真的不知道答案。

...setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)

Your question is explained here by the Espresso team: Espresso团队在此解释您的问题:

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. 幸运的是,Espresso为我们处理这个问题。

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

So I understand that both alternatives are correct but depend on your specific case. 所以我理解两种选择都是正确的,但取决于你的具体情况。 If you test a button you normally know if it's visible or not at that moment. 如果你测试一个按钮,你通常知道那时它是否可见。

In your case the button is visible because there is room, and it's correct to use withId like here : 你的情况的按钮可见,因为有房,这是正确的使用withId喜欢这里

import static android.support.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu;

@Test
public void testClickInsertItem() {
    openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());
    onView(withId(R.id.action_insert)).perform(click());
}

But this it's correct too for overflow items: 但是, 是正确的太溢出项目:

Yes, this is how it works in Espresso. 是的,这就是Espresso的工作原理。 The problem here is, that in Android, the View representing the menu item doesn't have the ID of the menu item. 这里的问题是,在Android中,表示菜单项的View没有菜单项的ID。 So onView(withId(X)) just fails to find a View. 因此onView(withId(X))无法找到View。 I don't have a better recommendation than just using withText(). 我没有比使用withText()更好的建议。 If you have multiple views with the same text, using hierarchy for distinction works. 如果您有多个具有相同文本的视图,则使用层次结构进行区分工作。

Now my question is what to do when you test on different devices and you don't know when will be room for an item. 现在我的问题是当你在不同的设备上进行测试时你该怎么做,而你不知道什么时候会有一个项目的空间。 I don't know the response, perhaps combine both solutions. 我不知道答案,也许结合两种解决方案。

You can use this method to click menu item. 您可以使用此方法单击菜单项。 First click menu button using this code 首先使用此代码单击菜单按钮

openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext());

Then perform click menu item based on text.Replace your menu item name with "MenuItemName" 然后根据文本执行单击菜单项。使用“MenuItemName”放置菜单项名称

onView(withText("MenuItemName")).perform(click());

This is my solution which covers all the three situations: hardware menu button, overflow menu, only icons: 这是我的解决方案,它涵盖了所有三种情况:硬件菜单按钮,溢出菜单,仅图标:

    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());
Espresso.openContextualActionModeOverflowMenu() 

was the only option that worked for my Samsung Note 3. This openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext()); 是我的三星Note 3唯一的选项。这个openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext()); would try and fail without any error 将尝试失败,没有任何错误

Use this to match on the description text for the menu item: 使用此选项匹配菜单项的描述文本:

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

Then you do not have to match on the (non-existent) ID, nor on the drawable icon. 然后,您不必匹配(不存在的)ID,也不必匹配可绘制的图标。

Also, remember to use this code snippet from the Espresso documentation if you need to make sure the menu is expanded: 此外,如果您需要确保扩展菜单,请记住使用Espresso文档中的此代码段:

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

Don't suffer a lot. 不要受苦很多。 Let's Make it simple . 让我们简单吧

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

This will help you to perform click on Add 这将帮助您执行单击“添加”

The toolbar is not the actionBar, no need of the call : 工具栏不是actionBar,不需要调用:

openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());

And if you do it, that's sure your item won't be found there (it's not in the ActionBar) and the ToolBar belongs to the "normal view". 如果你这样做,那肯定你的项目不会在那里找到(它不在ActionBar中)并且ToolBar属于“普通视图”。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM