AmbiguousViewMatcherException 多个 RecyclerViews
AmbiguousViewMatcherException multiple RecyclerViews
我有一个包含 RecyclerView
的 Fragment
。但是由于我在这个 Fragment
中有很多元素,我想向上滑动列表以查看并检查这个 Fragment
中的所有元素。
之前这个方法对我有帮助,但现在不知为何不起作用:
Espresso.onView(ViewMatchers.withId(R.id.recyclerView)).perform(ViewActions.swipeUp())
我的项目中有很多 RecyclerView
具有相同的 id
:
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"/>
在我的测试中我也写了这样的东西:
onView(allOf( withId(R.id.recyclerView), isDisplayed()))
onView(withId(R.id.recyclerView)).perform(swipeUp())
但只在第二行发现错误。
android.support.test.espresso.AmbiguousViewMatcherException: 'with id: com.fentury.android:id/recyclerView' matches multiple views in the hierarchy.
Problem views are marked with '****MATCHES****' below.
您的视图层次结构中有多个 ID 为 R.id.recyclerView
的视图,因此 espresso 无法执行正确的匹配。使 RecyclerView
中的 id
独一无二。
onView(allOf(withId(R.id.recyclerView), isDisplayed()))
onView(withId(R.id.recyclerView)).perform(swipeUp())
But caught error only on second line.
然后这样匹配:
onView(allOf(withId(R.id.recyclerView), isDisplayed())).perform(swipeUp())
您应该为回收站视图使用数据,您可以在其中使用回收站视图的 ID 及其保存的数据类型进行断言。这应该有助于假设不同的回收者视图不会具有相同类型的数据,但更好的做法是根据其用途为不同的视图使用不同的 ID。
您可能还想使用 perform(ViewActions.scrollTo())
当我发现这个问题时,我在 ViewPager 内的两个片段中遇到了多个 RecyclerView 的类似问题。
两个片段使用相同的布局文件,仅包含 ID = @id/list.
的 RecyclerView
因为没有匹配的父级,所以我制作了这个自定义 ViewMatcher 以匹配 Adapter-Class 的列表:(Kotlin)
fun hasAdapterOfType(T: Class<out RecyclerView.Adapter<out RecyclerView.ViewHolder>>): BoundedMatcher<View, RecyclerView> {
return object : BoundedMatcher<View, RecyclerView>(RecyclerView::class.java) {
override fun describeTo(description: Description) {
description.appendText("RecycleView adapter class matches " + T.name)
}
override fun matchesSafely(view: RecyclerView): Boolean {
return (view.adapter.javaClass.name == T.name)
}
}
}
这样的用法:
onView(allOf(withId(list), hasAdapterOfType(AccessAttemptListAdapter::class.java))).check(blabla)
解决方案:
onView(allOf(withId(R.id.recyclerview), isDisplayed())).perform(swipeUp());
我有一个包含 RecyclerView
的 Fragment
。但是由于我在这个 Fragment
中有很多元素,我想向上滑动列表以查看并检查这个 Fragment
中的所有元素。
之前这个方法对我有帮助,但现在不知为何不起作用:
Espresso.onView(ViewMatchers.withId(R.id.recyclerView)).perform(ViewActions.swipeUp())
我的项目中有很多 RecyclerView
具有相同的 id
:
<android.support.v7.widget.RecyclerView
android:id="@+id/recyclerView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="vertical"/>
在我的测试中我也写了这样的东西:
onView(allOf( withId(R.id.recyclerView), isDisplayed()))
onView(withId(R.id.recyclerView)).perform(swipeUp())
但只在第二行发现错误。
android.support.test.espresso.AmbiguousViewMatcherException: 'with id: com.fentury.android:id/recyclerView' matches multiple views in the hierarchy. Problem views are marked with '****MATCHES****' below.
您的视图层次结构中有多个 ID 为 R.id.recyclerView
的视图,因此 espresso 无法执行正确的匹配。使 RecyclerView
中的 id
独一无二。
onView(allOf(withId(R.id.recyclerView), isDisplayed()))
onView(withId(R.id.recyclerView)).perform(swipeUp())
But caught error only on second line.
然后这样匹配:
onView(allOf(withId(R.id.recyclerView), isDisplayed())).perform(swipeUp())
您应该为回收站视图使用数据,您可以在其中使用回收站视图的 ID 及其保存的数据类型进行断言。这应该有助于假设不同的回收者视图不会具有相同类型的数据,但更好的做法是根据其用途为不同的视图使用不同的 ID。
您可能还想使用 perform(ViewActions.scrollTo())
当我发现这个问题时,我在 ViewPager 内的两个片段中遇到了多个 RecyclerView 的类似问题。 两个片段使用相同的布局文件,仅包含 ID = @id/list.
的 RecyclerView因为没有匹配的父级,所以我制作了这个自定义 ViewMatcher 以匹配 Adapter-Class 的列表:(Kotlin)
fun hasAdapterOfType(T: Class<out RecyclerView.Adapter<out RecyclerView.ViewHolder>>): BoundedMatcher<View, RecyclerView> {
return object : BoundedMatcher<View, RecyclerView>(RecyclerView::class.java) {
override fun describeTo(description: Description) {
description.appendText("RecycleView adapter class matches " + T.name)
}
override fun matchesSafely(view: RecyclerView): Boolean {
return (view.adapter.javaClass.name == T.name)
}
}
}
这样的用法:
onView(allOf(withId(list), hasAdapterOfType(AccessAttemptListAdapter::class.java))).check(blabla)
解决方案:
onView(allOf(withId(R.id.recyclerview), isDisplayed())).perform(swipeUp());