2015-11-27 13 views
14

Mam menu w actionbar które tworzę poprzez:Espresso kliknij menu

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

i menu_main.xml wygląda następująco:

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

Podczas testowania w Espresso Chciałbym kliknij ikona "dodaj" (menuId 99). Spróbowałem

ale to się nie powiedzie z wyjątkiem NoMatchingViewException. (Element ustawień, który jest zdefiniowany w Xml bezpośrednio mogę kliknąć z tym samym kodem.)

To dla targetSdkVersion 23 i AppCompatActivity. Odpowiednie linie na pasku narzędzi są:

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

i tool_bar.xml wygląda następująco:

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

Co 'targetSdkVersion', ActionBar i urządzenia/emulator używasz ?. Zobacz implementacja openActionBarOverflowOrOptionsMenu() (klasa Espresso), zależy od tych czynników. Muszę to zbadać, ale coś jest nie tak, zależnie od używanego emulatora. – albodelu

+0

targetSdkVersion 23 i AppCompatActivity. Dodałem powyższy kod paska narzędzi. – user1583209

+0

Czy wystąpił problem z dopasowaniem tekstu do "withText (R.string.add)", ponieważ rzeczywisty tekst nie jest widoczny, ale widoczna jest tylko ikona (R.drawable.ic_add_white_48dp)? – user1583209

Odpowiedz

23

Aktualizacja: nie widzę końcowy linii, ignorować moje wcześniejsze odpowiedzi, Próbowałem to naprawić szybko i zrobiłem źle. Naprawdę nie znałem odpowiedzi.

...setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM) 

Twoje pytanie zostało wyjaśnione here przez zespół kawy:

Dopasowany widocznych ikon:

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

Kliknięcie pozycji w menu przelewowego jest nieco trudniejsze do normalny pasek akcji , ponieważ niektóre urządzenia mają przycisk menu sprzętowego przepełnienia (będą otwierać przepełnione pozycje w menu opcji), a niektóre urządzenia mają przycisk menu przepełnienia menu (otwierają normalne menu przepełnienia ). Na szczęście Espresso obsługuje to za nas.

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

Więc rozumiem, że obie alternatywy są poprawne, lecz zależy od konkretnego przypadku. Jeśli testujesz przycisk, który zwykle znasz, czy jest widoczny, czy nie w tym momencie.

W twoim przypadku przycisk jest widoczny, ponieważ nie ma miejsca, a to poprawne użycie withId jak here:

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

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

Ale this to poprawne zbyt przedmiotów overflow:

Tak, jak to działa w Espresso. Problem polega na tym, że w Android, Widok reprezentujący pozycję menu nie ma identyfikatora pozycji menu. Tak więc onView (withId (X)) po prostu nie może znaleźć widoku. Nie mam lepszej rekomendacji niż używanie withText(). Jeśli masz wiele widoków z tym samym tekstem, działa hierarchia dla rozróżnienia .

Teraz moje pytanie brzmi, co zrobić, gdy testujesz na różnych urządzeniach i nie wiesz, kiedy będzie miejsce na przedmiot. Nie znam odpowiedzi, być może łączę oba rozwiązania.

+0

Dzięki. A zatem nie można dopasować widocznej ikony za pomocą "withText()"? Jeśli to możliwe, chciałbym unikać używania "withId()", ponieważ w moim rozumieniu test powinien imitować działania użytkowników, a ludzie będą szukać tekstu/ikony zamiast (niewidzialnego) identyfikatora. – user1583209

+0

Nie wiem, poczekaj lepszej odpowiedzi, odpowiedziałem, ponieważ myślałem, że to ten sam problem, który ci skomentowałem. Zaktualizuję go, jeśli nikt nie odpowie i znajdę lepszą odpowiedź. Nigdy nie używałem SHOW_AS_ACTION_IF_ROOM i nadal uczę się Espresso. – albodelu

0

Pasek nie jest actionBar, bez konieczności wezwania:

openActionBarOverflowOrOptionsMenu(InstrumentationRegistry.getTargetContext()); 

A jeśli nie to, to, że Twój artykuł nie będzie tam znaleźć (nie jest w ActionBar) i paska narzędzi należy do "widoku normalnego".

2

Możesz użyć tej metody, aby kliknąć pozycję menu. Pierwszy przycisk menu kliknij przy użyciu tego kodu

openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext()); 

następnie wykonać kliknij menu w oparciu o text.Replace swoją nazwę pozycji menu z „MenuItemName”

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

był jedyną opcją, która pracowała dla mojego Uwaga Samsunga 3. To openActionBarOverflowOrOptionsMenu(getInstrumentation().getTargetContext()); spróbuje i zawiedzie bezbłędnie

0

To jest moje rozwiązanie, które obejmuje wszystkie trzy sytuacje: przycisk menu sprzętu, przelew m enu, tylko ikony:

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

Użyj tego, aby dopasować do tekstu opisu dla tego elementu menu:

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

Wtedy nie trzeba dopasować na (nieistniejącego) ID, ani na ikona losowania.

Ponadto, należy pamiętać, aby używać tego fragmentu kodu z the Espresso documentation jeśli trzeba upewnić się, że menu jest rozszerzona:

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

nie cierpią dużo. Let's Zrób to prosty.

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

To pomoże Ci wykonać kliknij Dodaj

+0

Wiem to. Ale wolałbym dopasować "withText()". Zobacz także mój komentarz do odpowiedzi albodelu. – user1583209

+0

Tekst nie pasuje do tego scenariusza, ponieważ Espresso w zasadzie znajduje tekst, który został wyświetlony na ekranie. Jednak używamy ikony, która nie ma żadnego tekstu. Nie możemy wykonać akcji za pomocą funkcji Text(). – Manish