Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to check MenuItem is enabled/disabled in Espresso UI Automation Test

I am writing UI Automation tests in Espresso for Android & came across a scenario for which I haven't got any solution so far.

In one Fragment, I have OptionsMenu with a single item. The state of that MenuItem is set according to value from API response.

@Override
public void onPrepareOptionsMenu(Menu menu) {
    super.onPrepareOptionsMenu(menu);
    menu.clear();
    getActivity().getMenuInflater().inflate(R.menu.menu_cancel_order, menu);
    MenuItem cancelMenuItem = menu.findItem(R.id.cancel_order);
    if(something) { // something can be a boolean value from server
        cancelMenuItem.setEnabled(true);
    } else {
        cancelMenuItem.setEnabled(false);
    } 
}

For UI testing, I need to write test case for checking whether this MenuItem is enabled/disabled.

For clicking on the overflowmenu,

ViewInteraction actionMenuItemView = onView(
            allOf(withId(R.id.action_settings), withContentDescription("Settings"), isDisplayed()));
actionMenuItemView.perform(click());

And so far what I have tried to check the Assertion is given below.

onView(allOf(withText("Cancel Order"), withId(R.id.cancel_order))).check(matches(not(isEnabled())));

But this fires NoMatchingViewException with message

NoMatchingViewException: No views in hierarchy found matching: (with text: is "Cancel Order" and with id: com.equinix.ecp.betatest:id/cancel_order)

So I tried changing it to

onView(allOf(withText("Cancel Order"))).check(matches(not(isEnabled())));

Somehow this matched the view but it was not a MenuItem but the TextView inside the MenuItem & since I am setting setEnabled() to MenuItem, check() Assertion won't work as expected since it is a TextView.

So my question is how to write Test for checking enabled/disabled state of MenuItem.

like image 495
sJy Avatar asked Apr 05 '17 04:04

sJy


People also ask

How do you check espresso visibility?

One simple way to check for a View or its subclass like a Button is to use method getVisibility from View class. I must caution that visibility attribute is not clearly defined in the GUI world. A view may be considered visible but may be overlapped with another view, for one example, making it hidden.

How do you assert espresso?

The most used assertion is the matches() assertion. It uses a ViewMatcher object to assert the state of the currently selected view. onView(...). check(matches(withText("Hello!")))

Which is the class used in espresso framework to identify mobile test objects?

Espresso testing library extends the necessary JUnit classes to support the Android based instrumentation testing.


1 Answers

it would be a good idea to make use of uiautomatorviewer, to put a breakpoint in at the point your test fails, and then inspect your app's layout for clues

it sounds to me that you have two views. One with the id of R.id.cancel_order and another with text "Cancel Order" which probably has another id (or could/should). So together they return NoMatchingView, because they aren't the same view.

They could be sibling views, or possibly one is a descendent of another. This is where uiautomatorviewer is very handy for figuring out what's happening on screen

as long as you've installed "Android SDK Platform-Tools" and "Android SDK Tools" from Terminal:

cd /Users/<user name>/Library/Android/sdk/tools/bin
./uiautomatorviewer

(it's also helpful to save this as a script and just use an alias shortcut for convenience)

as for your matcher, i would try :

onView(allOf(
    withId(R.id.cancel_order),
    hasSibling(withText("Cancel Order")) 
)).check(matches(not(isEnabled())));

or change hasSibling(_) to hasDescendent(_) or isDescendentOfA(_), depending on their relationship (which you can find out by using uiautomatorviewer)

like image 174
Emmaaa Avatar answered Oct 10 '22 19:10

Emmaaa