Android - espresso - clicking on a listview entry based on custom objects

tm1701 picture tm1701 · Aug 18, 2014 · Viewed 9.9k times · Source

Espresso is used for automatic testing my App.

Edit: below you find a number of answers!

How can I click (within an automated Espresso test script) on an entry in a long list of custom objects?

In the Espresso documentation there is an example of a LongList. Working with a List of objects is what I normally do. Trying many options to step from Map to Object didn't yield good results so far.

The Espresso documentation says a 'onData' should be used. So, something like:

onData( myObjectHasContent("my_item: 50")).perform(click());
onView(withId( R.id.selection_pos2)).check(matches(withText("50")));

My questions (and I think they are helpful for the learning community): - Can you write a good Matcher for this? - How can we use that in the 'onData' ?

What is the situation? On the screen I have a listview of objects like:

public class MyOjbect { 
    public String content; 
    public int    size; 
}

The adapter I use to populate the populated list is:

public class MyObjectWithItemAndSizeAdapter extends ArrayAdapter<MyObjectWithItemAndSize> {
    private final Context context;
    private final List<MyObjectWithItemAndSize> values;
    ...
    @Override
    public View getView(int position, View concertView, ViewGroup parent) {
        View view = null;
        if (concertView != null) {
            view = (LinearLayout) concertView;
        } else {
            LayoutInflater inflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
            view = inflater.inflate( R.layout.list_item, parent, false);
        } 
        TextView itemT = (TextView) view.findViewById( R.id.item_content);
        itemT.setText( values.get(position).item);
        TextView sizeT = (TextView) view.findViewById( R.id.item_size);
        sizeT.setText( "" + values.get(position).size);
        return view;
    }
 }

Answer

haffax picture haffax · Aug 19, 2014

The matcher given to onData() must match the desired value returned by Adapter.getItem(int) of the desired ListView.

So in your example, the matcher should be something like this:

public static Matcher<Object> withContent(final String content) {
    return new BoundedMatcher<Object, MyObjectWithItemAndSize>(MyObjectWithItemAndSize.class) {
        @Override
        public boolean matchesSafely(MyObjectWithItemAndSize myObj) {
            return myObj.content.equals(content);
        }

        @Override
        public void describeTo(Description description) {
            description.appendText("with content '" + content + "'");
        }
    };
}