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).
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)
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));
// ...
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));
// ...
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
Basé sur la réponse @ Sivakumar Kamichetty:
- la Variable 'COUNT' est accessible depuis la classe interne, doit être déclarée finale.
- Ligne inutilement:
COUNT = 0;
- transfert
COUNT
variable à un tableau d'éléments. - 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];
}
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))))