断言列表中含有适当数量的浓缩咖啡



检查和断言listview是android espresso的预期大小的最佳方法是什么?

我写了这个匹配器,但不太知道如何将它集成到测试中。

public static Matcher<View> withListSize (final int size) {
    return new TypeSafeMatcher<View> () {
        @Override public boolean matchesSafely (final View view) {
            return ((ListView) view).getChildCount () == size;
        }
        @Override public void describeTo (final Description description) {
            description.appendText ("ListView should have " + size + " items");
        }
    };
}

我明白了。

class Matchers {
  public static Matcher<View> withListSize (final int size) {
    return new TypeSafeMatcher<View> () {
      @Override public boolean matchesSafely (final View view) {
        return ((ListView) view).getCount () == size;
      }
      @Override public void describeTo (final Description description) {
        description.appendText ("ListView should have " + size + " items");
      }
    };
  }
}

如果期望列表中的一个项目,把它放在实际的测试脚本中。

onView (withId (android.R.id.list)).check (ViewAssertions.matches (Matchers.withListSize (1)));

有两种不同的方法来获取含有espresso的列表中的项目计数:第一个是上面提到的@CoryRoy -使用TypeSafeMatcher,另一个是使用BoundedMatcher

因为@CoryRoy已经展示了如何断言它,在这里我想告诉如何使用不同的匹配器获得(返回)数字。

public class CountHelper {
    private static int count;
    public static int getCountFromListUsingTypeSafeMatcher(@IdRes int listViewId) {
        count = 0;
        Matcher matcher = new TypeSafeMatcher<View>() {
            @Override
            protected boolean matchesSafely(View item) {
                count = ((ListView) item).getCount();
                return true;
            }
            @Override
            public void describeTo(Description description) {
            }
        };
        onView(withId(listViewId)).check(matches(matcher));
        int result = count;
        count = 0;
        return result;
    }
    public static int getCountFromListUsingBoundedMatcher(@IdRes int listViewId) {
        count = 0;
        Matcher<Object> matcher = new BoundedMatcher<Object, String>(String.class) {
            @Override
            protected boolean matchesSafely(String item) {
                count += 1;
                return true;
            }
            @Override
            public void describeTo(Description description) {
            }
        };
        try {
            // do a nonsense operation with no impact
            // because ViewMatchers would only start matching when action is performed on DataInteraction
            onData(matcher).inAdapterView(withId(listViewId)).perform(typeText(""));
        } catch (Exception e) {
        }
        int result = count;
        count = 0;
        return result;
    }
}

还想提一下,您应该使用ListView#getCount()而不是ListView#getChildCount():

  • getCount() - 适配器拥有的数据项数,可能大于可见视图数。
  • getChildCount() - ViewGroup中可以被ViewGroup重用的子节点个数。

在Kotlin和RecyclerView中,我使用了这段代码,灵感来自@Cory Roy的回答。

internal object Matchers {
    fun withRecyclerViewSize(size: Int): TypeSafeMatcher<View?> {
        return object : TypeSafeMatcher<View?>() {
            override fun describeMismatchSafely(item: View?, mismatchDescription: Description?) {
                mismatchDescription?.appendText("RecyclerView has ${(item as RecyclerView).childCount} item(s)")
            }
            override fun describeTo(description: Description) {
                description.appendText("RecyclerView should have $size item(s)")
            }
            override fun matchesSafely(item: View?): Boolean {
                return (item as RecyclerView).adapter?.itemCount == size
            }
        }
    }
}

像这样使用:

val recyclerView = onView(withId(R.id.rv_students))
recyclerView.check(ViewAssertions.matches(Matchers.withRecyclerViewSize(5)));

最新更新