Espresso onData perform click on multiple items

微笑、不失礼 提交于 2020-02-06 04:09:51

问题


I have a Gridview with an adapter based on a list of pojos of type Tile for my MineSweeper game, Im doing some unit tests and all I want to do is Click on all gridview Items that dont have mines and longclick all items that does have items

I have tried with the following:

onData(allOf(is(instanceOf(Tile.class)),isMineMatcher(true)))
            .inAdapterView(withId(R.id.f_minefield_gridview))
            .perform(longClick());

onData(allOf(is(instanceOf(Tile.class)),isMineMatcher(false)))
            .inAdapterView(withId(R.id.f_minefield_gridview))
            .perform(click());

with my custom matcher:

public static Matcher<Tile> isMineMatcher(final boolean flag){
    return new TypeSafeMatcher<Tile>() {
        @Override
        public boolean matchesSafely(Tile tile) {
            return tile.isMine() == flag;
        }

        @Override
        public void describeTo(Description description) {
            description.appendText("expected "+ flag);
        }
    };
}

But this presents the following error:

android.support.test.espresso.PerformException: Error performing 'load adapter data' on view 'with id: com.kaissersoft.minesweepergame:id/f_minefield_gridview'.
...
Caused by: java.lang.RuntimeException: Multiple data elements matched:

The question is how to perform Actions on Multiple items with espresso?


回答1:


Why don't you try as it is given in testDroid. It worked for me:

If you have other objects in your adapter:

public class Person {
   public long id;
   public String firstName;
   public String lastName;
   public String email;
}

You can use this with onData :

onData(allOf(is(new BoundedMatcher<Object, Person>(Person.class) {
    @Override
    public void describeTo(Description description) {
    }
    @Override
    protected boolean matchesSafely(Person obj) {
        return obj.id = 12345L;
    }
}))).inAdapterView(withId(<ADAPTER_ID>)).perform(click());

So now Person with id=12345 will be found in the adapter (during test execution) and it will be clicked.




回答2:


Simple answer: you don't.

The use case is misguided in the first place. The purpose of Automating UI Tests is to

write your UI tests such that user actions are performed in an automated way.

Ask yourself the following questions:

  1. Is this action performable by a real user? If so, how many fingers would he actually need?
  2. What would be the outcome of such an action? In your case, each separate click event would update the UI and mark that specific tile as visited. Does your code actually handle clicking on more tiles at the same time?

Espresso's behavior only handles performing actions on one view at a time.

I think a solution to that would be to iterate through all items in the gridview and perform the desired action on each of them.

Try using atPosition() to point to exactly one location at a time and perform the desired action.

onData(allOf(is(instanceOf(Tile.class)),isMineMatcher(true)))
        .inAdapterView(withId(R.id.f_minefield_gridview))
        .atPosition(1)
        .perform(longClick());



回答3:


Update:

I found out that you can simply add .atPosition(0) to your onData so it would perform your action/check on the first matched item:

onData(allOf(is(instanceOf(Tile.class)),isMineMatcher(true)))
            .atPosition(0)
            .inAdapterView(withId(R.id.f_minefield_gridview))
            .perform(longClick());

Old Answer:

I had a similar issue. I solved it by only returning true for the first match:

public static Matcher<Tile> isMineMatcher(final boolean flag){
    return new TypeSafeMatcher<Tile>() {
        boolean mFound;

        @Override
        public boolean matchesSafely(Tile tile) {
            // only match the first view :)
            if (mFound) return false;

            mFound = tile.isMine() == flag;
            return mFound;
        }

        @Override
        public void describeTo(Description description) {
            description.appendText("expected "+ flag);
        }
    };
}


来源:https://stackoverflow.com/questions/29813336/espresso-ondata-perform-click-on-multiple-items

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!