2015-11-27 3 views
14

У меня есть меню в 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; 
} 

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

При тестировании в Эспрессо я хотел нажать на значок «добавить» (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> 
+0

Что 'targetSdkVersion', ActionBar и устройство/эмулятор вы используете ?. См. Реализацию openActionBarOverflowOrOptionsMenu() (класс Espresso), зависит от этих факторов. Мне нужно исследовать его, но там что-то не так, в зависимости от используемого эмулятора. – albodelu

+0

targetSdkVersion 23 и AppCompatActivity. Я добавил код панели инструментов выше. – user1583209

+0

Может возникнуть проблема при сопоставлении текста с «withText (R.string.add)», поскольку фактический текст не отображается, но только значок (R.drawable.ic_add_white_48dp) виден? – user1583209

ответ

23

Update: Я не видел окончательные линии, игнорировать мои предыдущие ответы, Я попытался исправить это быстро, и я сделал не так. Я действительно не знал ответа.

...setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM) 

Ваш вопрос объясняется here командой Эспрессо:

Matching видимые иконки:

// 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, представление, представляющее пункт меню, не имеет идентификатора пункта меню. Поэтому onView (withId (X)) просто не находит View. У меня нет , чтобы получить лучшую рекомендацию, чем просто использовать withText(). Если у вас есть несколько просмотров с тем же текстом, используя иерархию для разметки works.

Теперь мой вопрос заключается в том, что делать, когда вы тестируете на разных устройствах, и вы не знаете, когда будет место для предмета. Я не знаю ответа, возможно, сочетаю оба решения.

+0

Спасибо. Таким образом, невозможно совместить видимый значок с помощью «withText()»? Если возможно, я бы хотел как можно больше избегать использования «withId()», поскольку в моем понимании тест должен имитировать действия пользователя, и люди искали бы текст/значок, а не для (невидимого) идентификатора. – user1583209

+0

Я не знаю, подожду лучшего ответа, я ответил, потому что думал, что это та самая проблема, о которой я прокомментировал. Я обновлю его, если никто не ответит, и я найду лучший ответ. Я никогда не использовал SHOW_AS_ACTION_IF_ROOM, и я все еще изучаю эспрессо. – albodelu

0

Панель инструментов не ActionBar, нет необходимости вызова:

openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext()); 

И если вы это делаете, это, что ваш товар не будет найден там (это не в ActionBar) и ToolBar относится к «нормальному виду».

2

Этот метод можно использовать, чтобы щелкнуть пункт меню. Кнопка Первого меню нажмите с помощью этого кода

openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext()); 

Затем выполнить пункт меню щелчка, основываясь на text.Replace меню имени элемента с «MenuItemName»

onView(withText("MenuItemName")).perform(click()); 
1
Espresso.openContextualActionModeOverflowMenu() 

был единственным вариантом, который работал на моем Samsung Note 3. Это openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext()); попытается и не получится без ошибок

0

Это мое решение, которое охватывает все три ситуации: меню аппаратного меню, переполнение m ЕНУ только иконки:

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

Используйте это, чтобы соответствовать по тексту описания для данного пункта меню:

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

Не много страдать. Let's Сделать это просто.

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

Это поможет вам выполнить нажмите на Добавить

+0

Это я знаю. Но я бы предпочел сопоставить «withText()». Также см. Мой комментарий к ответу albodelu. – user1583209

+0

С текстом не подходит для этого сценария, потому что Espresso в основном находит текст, который был показан на экране. Однако мы используем Icon, который не имеет никакого текста. Мы не можем выполнять действия с Text(). – Manish

Смежные вопросы