如何让Espresso单击特定的RecyclerView项目? [英] How to let Espresso click a specific RecyclerView item?
问题描述
我正在尝试为使用RecyclerView
的Android应用编写 Espresso 的检测测试.这是主要布局:
I am trying to write an instrumentation test with Espresso for my Android app which uses a RecyclerView
. Here is the main layout:
<?xml version="1.0" encoding="utf-8"?>
<android.support.design.widget.CoordinatorLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent">
<android.support.v7.widget.RecyclerView
android:id="@+id/grid"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_behavior="@string/appbar_scrolling_view_behavior"/>
</android.support.design.widget.CoordinatorLayout>
...以及项目视图的布局:
... and the item view layout:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent">
<TextView
android:id="@+id/label"
android:layout_width="match_parent"
android:layout_height="wrap_content"/>
</RelativeLayout>
这意味着屏幕上有几个TextViews
,都具有label
id.我正在尝试单击特定的标签.我试图让Espresso测试记录器生成代码:
This means there are a couple of TextViews
on the screen which all have the label
id. I am trying to click a specific label. I tried to let Espresso test recorder generate the code:
onView(allOf(withId(R.id.grid), isDisplayed()))
.perform(actionOnItemAtPosition(5, click()));
我想做类似的事情:
// Not working
onView(allOf(withId(R.id.grid), isDisplayed()))
.perform(actionOnItem(withText("Foobar"), click()));
阅读
我阅读了很多有关该主题的内容,但仍然无法弄清楚如何根据其内容不是基于其位置索引来测试RecyclerView
项目.
Readings
I read quite a bit about the topic but still cannot figure out how to test a RecyclerView
item based on its content not based on its position index.
- 高级Android浓咖啡-在RecyclerViewActions上滑动(Chiu-Ki陈)
- RecyclerView和espresso,一个复杂的故事(帕特里克·培根,2015年7月18日)
- Espresso –在特定位置测试RecyclerViews (罗曼·皮尔(Romain Piel),2016年4月15日)
- Advanced Android Espresso - Slide on RecyclerViewActions (Chiu-Ki Chan)
- RecyclerView and espresso, a complicated story (Patrick Bacon, Jul 18, 2015)
- Espresso – Testing RecyclerViews at Specific Positions (Romain Piel, April 15, 2016)
推荐答案
您可以实现自定义的RecyclerView
匹配器.假设您有RecyclerView
,其中每个元素都有要匹配的主题:
You can implement your custom RecyclerView
matcher. Let's assume you have RecyclerView
where each element has subject you want to match:
public static Matcher<RecyclerView.ViewHolder> withItemSubject(final String subject) {
Checks.checkNotNull(subject);
return new BoundedMatcher<RecyclerView.ViewHolder, MyCustomViewHolder>(
MyCustomViewHolder.class) {
@Override
protected boolean matchesSafely(MyCustomViewHolder viewHolder) {
TextView subjectTextView = (TextView)viewHolder.itemView.findViewById(R.id.subject_text_view_id);
return ((subject.equals(subjectTextView.getText().toString())
&& (subjectTextView.getVisibility() == View.VISIBLE)));
}
@Override
public void describeTo(Description description) {
description.appendText("item with subject: " + subject);
}
};
}
和用法:
onView(withId(R.id.my_recycler_view_id)
.perform(RecyclerViewActions.actionOnHolderItem(withItemSubject("My subject"), click()));
基本上,您可以匹配任何您想要的东西.在此示例中,我们使用主题TextView
,但它可以是RecyclerView
项内的任何元素.
Basically you can match anything you want. In this example we used subject TextView
but it can be any element inside the RecyclerView
item.
要澄清的另一件事是检查可见性(subjectTextView.getVisibility() == View.VISIBLE)
.我们需要使用它,因为有时RecyclerView
中的其他视图可以具有相同的主题,但对于View.GONE
而言却是这样.这样,我们就避免了自定义匹配器的多次匹配,并且只定位了实际显示主题的项目.
One more thing to clarify is check for visibility (subjectTextView.getVisibility() == View.VISIBLE)
. We need to have it because sometimes other views inside RecyclerView
can have the same subject but it would be with View.GONE
. This way we avoid multiple matches of our custom matcher and target only item that actually displays our subject.
这篇关于如何让Espresso单击特定的RecyclerView项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!