【问题标题】:Espresso click menu item浓缩咖啡点击菜单项
【发布时间】:2015-11-27 22:54:27
【问题描述】:

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

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

【问题讨论】:

  • 你在使用什么targetSdkVersion、ActionBar 和设备/模拟器?。请参阅 openActionBarOverflowOrOptionsMenu() 实现(Espresso 类),取决于这些因素。我需要调查它,但根据我使用的模拟器,那里有问题。
  • targetSdkVersion 23 和 AppCompatActivity。我在上面添加了工具栏代码。
  • 用“withText(R.string.add)”匹配文本时会不会出现问题,因为实际文本不可见,但只有图标(R.drawable.ic_add_white_48dp)可见?
  • 这是在 Sony Xperia SP(真实设备,而非模拟器)上。
  • 不是解决方案,但我注意到“onView(withId(99)).perform(click());”有效,即使我记得在某处读到那些“menu-Id”与“view-id”不同......

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


【解决方案1】:

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

...setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)

Espresso 团队在here 解释了您的问题:

匹配可见图标:

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

单击溢出菜单中的项目对于 正常操作栏,因为某些设备具有硬件溢出菜单按钮 (他们将在选项菜单中打开溢出的项目)和一些 设备有一个软件溢出菜单按钮(它们将打开一个正常的 溢出菜单)。幸运的是,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());

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

在你的情况下,按钮是可见的,因为有空间,使用withId 就像here 是正确的:

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

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

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

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

现在我的问题是,当您在不同的设备上进行测试并且您不知道什么时候可以容纳某个项目时该怎么办。我不知道响应,也许结合两种解决方案。

【讨论】:

  • 谢谢。所以不可能使用“withText()”来匹配一个可见的图标?如果可能的话,我想尽可能避免使用“withId()”,因为据我了解,测试应该模仿用户操作,而人类会寻找文本/图标而不是(不可见的)id。
  • 我不知道,等待更好的回复,我回答是因为我认为这是我评论你的同一个问题。如果没有人回答,我会更新它,我会找到更好的回答。我从未使用过 SHOW_AS_ACTION_IF_ROOM,而且我还在学习 Espresso。
【解决方案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】:

    使用它来匹配菜单项的描述文本:

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

    那么您不必匹配(不存在的)ID,也不必匹配可绘制图标。

    另外,如果您需要确保菜单已展开,请记住使用来自the Espresso documentation 的代码 sn-p:

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

    【讨论】:

    • 这是适用于 withText() 不适用的所有情况的最佳解决方案!它也适用于仅图标项目 (app:showAsAction="always")。只需添加&lt;item ...android:contentDescription="@string/R.string.add" 并使用withContentDescription(R.string.add)
    【解决方案4】:

    不要受太多苦。让我们让它变得简单

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

    这将帮助您执行点击添加

    【讨论】:

    • 这个我知道。但我更喜欢匹配“withText()”。另请参阅我对 albodelu 的回答的评论。
    • With Text 不适合这种情况,因为 Espresso 基本上会找到屏幕上显示的文本。但是我们使用没有任何文本的图标。我们无法使用 Text() 执行操作。
    【解决方案5】:

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

    openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext());
    

    然后根据文本执行单击菜单项。将您的菜单项名称替换为“MenuItemName”

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

    【讨论】:

      【解决方案6】:
      Espresso.openContextualActionModeOverflowMenu() 
      

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

      【讨论】:

        【解决方案7】:

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

        openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());
        

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

        【讨论】:

          猜你喜欢
          • 2015-10-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-10-15
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多