Espresso - 如何在回收站视图中查找特定项目(顺序是随机的)
Espresso - how to find a specific item in a recycler view (order is random)
我想知道如何在回收站视图中找到特定项目,其中项目的顺序是随机的 运行。
假设我在回收站视图中有 4 个项目,每个项目都由相同类型的视图持有者表示,其中有一个文本视图。每个视图都应用了一个唯一的标题 holder/item。对于这个例子,为了简单起见,假设标题是 "A"、"B"、"C" 和 "D".
如果顺序是随机的,我如何找到位置(然后单击)项目 "A"?我知道如果订单没有改变,我可以执行 scrollToPosition RecyclerViewInteraction 操作,但在这种情况下,订单可以而且将会改变。
有什么想法吗?
使用 Espresso.onData
使用自定义视图匹配器。 Google example
我已经使用了一些可以像这样适应你的情况的东西:
onData(new BaseMatcher<String>() {
@Override
public void describeTo(Description description) {
// what?
description.appendText("Matches A");
}
@Override
public boolean matches(Object item) {
return item instanceof String && ((String) item).equals("A");
}
}).perform(click());
你可以用任何你的模型类型替换 String
如果它比它更复杂,并且如果它很简单也可以使用内置匹配器(这种情况可以通过 onData(is("A")).perform(click())
).
我能够通过以下操作使它正常工作:
Matcher<RecyclerView.ViewHolder> matcher = CustomMatcher.withTitle("A");
onView((withId(R.id.recycler_view))).perform(scrollToHolder(matcher), actionOnHolderItem(matcher, click()));
其中 CustomMatcher.withTitle
是:
public static Matcher<RecyclerView.ViewHolder> withTitle(final String title)
{
return new BoundedMatcher<RecyclerView.ViewHolder, CustomListAdapter.ItemViewHolder>(CustomListAdapter.ItemViewHolder.class)
{
@Override
protected boolean matchesSafely(CustomListAdapter.ItemViewHolder item)
{
return item.mTitleView.getText().toString().equalsIgnoreCase(title);
}
@Override
public void describeTo(Description description)
{
description.appendText("view holder with title: " + title);
}
};
}
我知道这是一个老问题,虽然@Zach 的回答是一个好的开始,并帮助我回答,我们有一个回收器视图,其中包含大量不同类型的 ViewHolders,对于答案没有的文本具有不同的 ID完全适合我们的用例。
我最后做的是使用稍微不同的匹配器,它不引用任何特定的 ID 或变量:
fun withText(title: String) = object : BoundedMatcher<View, View>(View::class.java) {
override fun describeTo(description: Description?) {
description?.appendText("Searching for title with: $title")
}
override fun matchesSafely(item: View?): Boolean {
val views = ArrayList<View>()
item?.findViewsWithText(views, title, View.FIND_VIEWS_WITH_TEXT)
return when {
views.size == 1 -> true
else -> false
}
}
}
和用法:
RecyclerViewActions.scrollTo<ViewHolder>(withText("Some unique text I'm looking for")
您不需要自定义匹配器,只需使用它
onView(withId(R.id.recycler_id)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText("A")), click()));
并添加 espresso-contrib 依赖项
androidTestImplementation 'com.android.support.test.espresso:espresso-contrib:<espressso-version>'
或者,如果您使用的是 AndroidX
androidTestImplementation 'androidx.test.espresso:espresso-contrib:<espressso-version>'
我想知道如何在回收站视图中找到特定项目,其中项目的顺序是随机的 运行。
假设我在回收站视图中有 4 个项目,每个项目都由相同类型的视图持有者表示,其中有一个文本视图。每个视图都应用了一个唯一的标题 holder/item。对于这个例子,为了简单起见,假设标题是 "A"、"B"、"C" 和 "D".
如果顺序是随机的,我如何找到位置(然后单击)项目 "A"?我知道如果订单没有改变,我可以执行 scrollToPosition RecyclerViewInteraction 操作,但在这种情况下,订单可以而且将会改变。
有什么想法吗?
使用 Espresso.onData
使用自定义视图匹配器。 Google example
我已经使用了一些可以像这样适应你的情况的东西:
onData(new BaseMatcher<String>() {
@Override
public void describeTo(Description description) {
// what?
description.appendText("Matches A");
}
@Override
public boolean matches(Object item) {
return item instanceof String && ((String) item).equals("A");
}
}).perform(click());
你可以用任何你的模型类型替换 String
如果它比它更复杂,并且如果它很简单也可以使用内置匹配器(这种情况可以通过 onData(is("A")).perform(click())
).
我能够通过以下操作使它正常工作:
Matcher<RecyclerView.ViewHolder> matcher = CustomMatcher.withTitle("A");
onView((withId(R.id.recycler_view))).perform(scrollToHolder(matcher), actionOnHolderItem(matcher, click()));
其中 CustomMatcher.withTitle
是:
public static Matcher<RecyclerView.ViewHolder> withTitle(final String title)
{
return new BoundedMatcher<RecyclerView.ViewHolder, CustomListAdapter.ItemViewHolder>(CustomListAdapter.ItemViewHolder.class)
{
@Override
protected boolean matchesSafely(CustomListAdapter.ItemViewHolder item)
{
return item.mTitleView.getText().toString().equalsIgnoreCase(title);
}
@Override
public void describeTo(Description description)
{
description.appendText("view holder with title: " + title);
}
};
}
我知道这是一个老问题,虽然@Zach 的回答是一个好的开始,并帮助我回答,我们有一个回收器视图,其中包含大量不同类型的 ViewHolders,对于答案没有的文本具有不同的 ID完全适合我们的用例。
我最后做的是使用稍微不同的匹配器,它不引用任何特定的 ID 或变量:
fun withText(title: String) = object : BoundedMatcher<View, View>(View::class.java) {
override fun describeTo(description: Description?) {
description?.appendText("Searching for title with: $title")
}
override fun matchesSafely(item: View?): Boolean {
val views = ArrayList<View>()
item?.findViewsWithText(views, title, View.FIND_VIEWS_WITH_TEXT)
return when {
views.size == 1 -> true
else -> false
}
}
}
和用法:
RecyclerViewActions.scrollTo<ViewHolder>(withText("Some unique text I'm looking for")
您不需要自定义匹配器,只需使用它
onView(withId(R.id.recycler_id)).perform(RecyclerViewActions.actionOnItem(hasDescendant(withText("A")), click()));
并添加 espresso-contrib 依赖项
androidTestImplementation 'com.android.support.test.espresso:espresso-contrib:<espressso-version>'
或者,如果您使用的是 AndroidX
androidTestImplementation 'androidx.test.espresso:espresso-contrib:<espressso-version>'