2016-04-04 2 views
27

Использование Espresso и Hamcrest,Как подсчитать RecyclerView элементы с Espresso

Как я могу рассчитывать количество элементов, доступных в recyclerView?

Пример: Я хотел бы проверить, отображаются ли 5 ​​элементов в определенном RecyclerView (при необходимости прокручивается).

ответ

50

Вот пример ViewAssertion проверить подсчет 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)); 
    } 
} 

, а затем использовать это утверждение

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

Я начал писать библиотеку, которая должна сделать тестирование более простым с эспрессо и uiautomator , Это включает в себя инструменты для действий и утверждений RecyclerView. https://github.com/nenick/espresso-macchiato Смотрите, например, EspRecyclerView с помощью метода assertItemCountIs (межд)

+0

Этот тест всегда проходит. Я не думаю, что он работает правильно. –

+0

adapter.getItemCount() подходит null..Can u pls, дайте мне знать причину этого. –

+0

@ AdamHurwitz Многие подтвердили, что эта работа, но, пожалуйста, объясните вашу ситуацию, когда она всегда проходит. – nenick

13

Для завершения nenick ответа и обеспечить и немного более гибкое решение, чтобы также проверить, если элемент соиЬ является 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); 
    } 

} 

Использование :

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

Добавление немного сахара синтаксиса к @Stephane's answer.

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

Использование:

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

Замечательно. Я бы предложил получить это в эспрессо, потому что действительно странно, что такая основная функция недоступна. – Samuel

3

Я использовал метод ниже, чтобы получить отсчет 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; 
    } 

использования -

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

Затем выполните утверждения, чтобы проверить, itemsCount как ожидается

1

основе @Sivakumar Kamichetty ответ:

  1. Variable 'COUNT' доступен изнутри внутреннего класса, должен быть объявлен окончательным.
  2. Нередко линия: COUNT = 0;
  3. Передача COUNT Переменная в один элемент массива.
  4. Переменный result не нужен.

Не приятно, но работает:

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