sheet intended cheat java android testing android-actionbar android-espresso

java - intended - Espresso haga clic en el elemento del menú



android espresso intended (7)

Tengo un menú en la barra de acción que creo a través de:

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

y menu_main.xml se ve como:

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

Al realizar una prueba en Espresso, me gustaría hacer clic en el icono "agregar" (menúId 99). Lo intenté

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

pero esto falla con una NoMatchingViewException. (El elemento de configuración, que se define en el xml directamente, puedo hacer clic con el mismo código).

Eso es para targetSdkVersion 23 y AppCompatActivity. Las líneas relevantes para la barra de herramientas son:

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

y tool_bar.xml se ve así:

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


Esta es mi solución que cubre las tres situaciones: botón de menú de hardware, menú de desbordamiento, solo iconos:

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


La barra de herramientas no es la barra de acción, no hay necesidad de la llamada:

openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext());

Y si lo haces, seguro que tu elemento no se encontrará allí (no está en la barra de acción) y que la barra de herramientas pertenece a la "vista normal".


No sufras mucho. Hagámoslo simple .

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

Esto le ayudará a realizar clic en Agregar


Puede utilizar este método para hacer clic en el elemento del menú. Primero haga clic en el botón de menú usando este código

openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext());

Luego realice un clic en el elemento del menú según el texto. Reemplace el nombre de su elemento del menú con "MenuItemName"

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


Use esto para hacer coincidir en el texto de descripción para el elemento de menú:

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

Entonces no tiene que coincidir en la ID (inexistente), ni en el icono dibujable.

Además, recuerde usar este fragmento de código de la documentación de Espresso si necesita asegurarse de que el menú esté expandido:

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


Actualización : no vi la final de la línea, ignoré mis respuestas anteriores, traté de arreglarlo rápido y lo hice mal. Realmente no sabía la respuesta.

...setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM)

Su pregunta es explicada here por el equipo de Espresso:

Haciendo coincidir los iconos visibles:

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

Hacer clic en los elementos en el menú de desbordamiento es un poco más complicado para la barra de acción normal ya que algunos dispositivos tienen un botón de menú de desbordamiento de hardware (abrirán los elementos desbordados en un menú de opciones) y algunos dispositivos tienen un botón de menú de desbordamiento de software un menú de desbordamiento normal). Afortunadamente, Espresso se encarga de eso para nosotros.

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

Entonces entiendo que ambas alternativas son correctas pero dependen de su caso específico. Si prueba un botón, normalmente sabe si está visible o no en ese momento.

En su caso, el botón es visible porque hay espacio, y es correcto usarlo con withId como here :

import static android.support.test.espresso.Espresso.openActionBarOverflowOrOptionsMenu; @Test public void testClickInsertItem() { openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext()); onView(withId(R.id.action_insert)).perform(click()); }

Pero this también es correcto para los artículos de desbordamiento:

Sí, así es como funciona en Espresso. El problema aquí es que, en Android, la Vista que representa el elemento del menú no tiene la ID del elemento del menú. Así que onView (withId (X)) simplemente no encuentra una vista. No tengo una mejor recomendación que solo usar withText (). Si tiene varias vistas con el mismo texto, el uso de la jerarquía para la distinción funciona.

Ahora mi pregunta es qué hacer cuando prueba en diferentes dispositivos y no sabe cuándo habrá espacio para un elemento. No sé la respuesta, tal vez combinar ambas soluciones.


Espresso.openContextualActionModeOverflowMenu()

fue la única opción que funcionó para mi Samsung Note 3. Este openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext()); trataría y fallaría sin ningún error