Comment compter les articles RecyclerView avec Espresso

En utilisant Espresso et Hamcrest,

Comment puis-je compter le nombre d'articles disponibles dans un recyclerView?

Exemple: je voudrais vérifier si 5 éléments s'affichent dans un RecyclerView spécifique (défilement si nécessaire).

37
demandé sur Willi Mentzel 2016-04-04 13:07:55

6 réponses

Voici un exemple ViewAssertion pour vérifier le nombre D'éléments RecyclerView

public class RecyclerViewItemCountAssertion implements ViewAssertion {
  private final int expectedCount;

  public RecyclerViewItemCountAssertion(int expectedCount) {
    this.expectedCount = expectedCount;
  }

  @Override
  public void check(View view, NoMatchingViewException noViewFoundException) {
    if (noViewFoundException != null) {
        throw noViewFoundException;
    }

    RecyclerView recyclerView = (RecyclerView) view;
    RecyclerView.Adapter adapter = recyclerView.getAdapter();
    assertThat(adapter.getItemCount(), is(expectedCount));
  }
}

Puis utilisez cette assertion

onView(withId(R.id.recyclerView)).check(new RecyclerViewItemCountAssertion(5));

j'ai commencé à écrire une bibliothèque qui devrait rendre les tests plus simples avec espresso et uiautomator. Cela inclut l'outillage pour L'action RecyclerView et les assertions. https://github.com/nenick/espresso-macchiato Voir par exemple EspRecyclerView avec la méthode assertItemCountIs (int)

62
répondu nenick 2017-01-31 23:46:13

Ajouter un peu de sucre de syntaxe à la réponse de @Stephane .

public class RecyclerViewItemCountAssertion implements ViewAssertion {
    private final Matcher<Integer> matcher;

    public static RecyclerViewItemCountAssertion withItemCount(int expectedCount) {
        return withItemCount(is(expectedCount));
    }

    public static RecyclerViewItemCountAssertion withItemCount(Matcher<Integer> matcher) {
        return new RecyclerViewItemCountAssertion(matcher);
    }

    private RecyclerViewItemCountAssertion(Matcher<Integer> matcher) {
        this.matcher = matcher;
    }

    @Override
    public void check(View view, NoMatchingViewException noViewFoundException) {
        if (noViewFoundException != null) {
            throw noViewFoundException;
        }

        RecyclerView recyclerView = (RecyclerView) view;
        RecyclerView.Adapter adapter = recyclerView.getAdapter();
        assertThat(adapter.getItemCount(), matcher);
    }
}

Utilisation:

import static your.package.RecyclerViewItemCountAssertion.withItemCount;

onView(withId(R.id.recyclerView)).check(withItemCount(5));
onView(withId(R.id.recyclerView)).check(withItemCount(greaterThan(5));
onView(withId(R.id.recyclerView)).check(withItemCount(lessThan(5));
// ...
23
répondu Brais Gabin 2017-05-23 12:26:23

Pour compléter la réponse de nenick et fournir une solution un peu plus flexible pour tester également si item cout est greaterThan, lessThan ...

public class RecyclerViewItemCountAssertion implements ViewAssertion {

    private final Matcher<Integer> matcher;

    public RecyclerViewItemCountAssertion(int expectedCount) {
        this.matcher = is(expectedCount);
    }

    public RecyclerViewItemCountAssertion(Matcher<Integer> matcher) {
        this.matcher = matcher;
    }

    @Override
    public void check(View view, NoMatchingViewException noViewFoundException) {
        if (noViewFoundException != null) {
            throw noViewFoundException;
        }

        RecyclerView recyclerView = (RecyclerView) view;
        RecyclerView.Adapter adapter = recyclerView.getAdapter();
        assertThat(adapter.getItemCount(), matcher);
    }

}

Utilisation:

onView(withId(R.id.recyclerView)).check(new RecyclerViewItemCountAssertion(5));
onView(withId(R.id.recyclerView)).check(new RecyclerViewItemCountAssertion(greaterThan(5));
onView(withId(R.id.recyclerView)).check(new RecyclerViewItemCountAssertion(lessThan(5));
// ...
14
répondu Stéphane 2017-01-31 23:48:05

J'ai utilisé la méthode ci-dessous pour obtenir le nombre de RecyclerView

public static int getCountFromRecyclerView(@IdRes int RecyclerViewId) {
int COUNT = 0;
        Matcher matcher = new TypeSafeMatcher<View>() {
            @Override
            protected boolean matchesSafely(View item) {
                COUNT = ((RecyclerView) item).getAdapter().getItemCount();
                return true;
            }
            @Override
            public void describeTo(Description description) {
            }
        };
        onView(allOf(withId(RecyclerViewId),isDisplayed())).check(matches(matcher));
        int result = COUNT;
            COUNT = 0;
        return result;
    }

Utilisation -

int itemsCount = getCountFromRecyclerView(R.id.RecyclerViewId);

Ensuite, effectuez des assertions pour vérifier si itemsCount est comme prévu

4
répondu Sivakumar Kamichetty 2017-08-02 08:50:28

Basé sur la réponse @ Sivakumar Kamichetty:

  1. la Variable 'COUNT' est accessible depuis la classe interne, doit être déclarée finale.
  2. Ligne inutilement: COUNT = 0;
  3. transfert COUNT variable à un tableau d'éléments.
  4. la Variable result n'est pas nécessaire.

Pas agréable, mais fonctionne:

public static int getCountFromRecyclerView(@IdRes int RecyclerViewId) {
    final int[] COUNT = {0};
    Matcher matcher = new TypeSafeMatcher<View>() {
        @Override
        protected boolean matchesSafely(View item) {
            COUNT[0] = ((RecyclerView) item).getAdapter().getItemCount();
            return true;
        }
        @Override
        public void describeTo(Description description) {}
    };
    onView(allOf(withId(RecyclerViewId),isDisplayed())).check(matches(matcher));
    return COUNT[0];
}
4
répondu t0m 2017-12-22 14:24:42

Vous pouvez créer un BoundedMatcher personnalisé:

object RecyclerViewMatchers {
    @JvmStatic
    fun hasItemCount(itemCount: Int): Matcher<View> {
        return object : BoundedMatcher<View, RecyclerView>(
            RecyclerView::class.java) {

            override fun describeTo(description: Description) {
                description.appendText("has $itemCount items")
            }

            override fun matchesSafely(view: RecyclerView): Boolean {
                return view.adapter.itemCount == itemCount
            }
        }
    }
}

Et puis utilisez-le comme ceci:

onView(withId(R.id.recycler_view)).check(matches((hasItemCount(5))))
0
répondu makovkastar 2018-05-02 09:03:38