2016-04-04 24 views
27

Verwenden von Espresso und Hamcrest,So zählen Sie RecyclerView-Artikel mit Espresso

Wie kann ich die in einem recyclerView verfügbare Artikelnummer zählen?

Beispiel: Ich möchte überprüfen, ob 5 Elemente in einer bestimmten RecyclerView angezeigt werden (Scrollen wenn nötig).

Antwort

50

Hier ist ein Beispiel ViewAssertion zu überprüfen RecyclerView Artikel

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)); 
    } 
} 

und verwenden dann diese Behauptung

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

Ich begann eine Bibliothek zu schreiben haben, zählen die Prüfung einfacher mit Espresso und uiautomator machen sollte . Dies beinhaltet Tools für RecyclerView-Aktionen und -Assizements. https://github.com/nenick/espresso-macchiato Siehe zum Beispiel EspRecyclerView mit der Methode assertItemCountIs (int)

+0

Dieser Test immer passiert. Ich glaube nicht, dass es richtig funktioniert. –

+0

adapter.getItemCount() kommt null..Kann uns den Grund dafür wissen lassen. –

+0

@AdamHurwitz viele haben bestätigt, dass dies funktioniert, aber bitte erläutern Sie Ihre Situation, wo es immer passieren. – nenick

13

nenick Antwort und bieten und wenig flexiblere Lösung vervollständigen auch zu testen, ob Artikel cout ist 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); 
    } 

} 

Nutzungs :

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)); 
// ... 
12

ein wenig Syntax Zucker zum @Stephane's answer hinzufügen.

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); 
    } 
} 

Verbrauch:

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)); 
// ... 
+0

Wunderbar. Ich würde vorschlagen, dies in Espresso zu bekommen, weil es wirklich seltsam ist, dass eine solche Kernfunktion nicht verfügbar ist. – Samuel

3

ich die unter Methode die Anzahl der 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; 
    } 

Nutzungsgewöhnungs -

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

Dann führen Behauptungen, wenn die überprüfen itemsCount ist wie erwartet

1

Basierend auf @Sivakumar Kamichetty Antwort:

  1. Variable 'COUNT' von innen inneren Klasse zugegriffen wird, muss, als final deklariert werden.
  2. Unnötig Zeile: COUNT = 0;
  3. Übertragung COUNT Variable auf ein Element-Array.
  4. Variable result ist nicht erforderlich.

Nicht schön, aber funktioniert:

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]; 
}