我正在尝试使用 Espresso 为我的 Android 应用程序编写一个仪器测试,该应用程序使用 RecyclerView
。这是主要布局:
<?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>
...和项目 View 布局:
<?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 测试记录器生成代码:
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
项目。
- Advanced Android Espresso - Slide on RecyclerViewActions (陈超基)
- RecyclerView and espresso, a complicated story (帕特里克培根,2015 年 7 月 18 日)
- Espresso – Testing RecyclerViews at Specific Positions (罗曼· PIL ,2016 年 4 月 15 日)
最佳答案
您可以实现自定义 RecyclerView
匹配器。假设您有 RecyclerView
,其中每个元素都有您要匹配的主题:
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
项目内的任何元素。
另一件需要澄清的事情是检查可见性 (subjectTextView.getVisibility() == View.VISIBLE)
。我们需要它,因为有时 RecyclerView
中的其他 View 可能具有相同的主题,但它会与 View.GONE
一起使用。这样我们就避免了自定义匹配器的多次匹配,并且只定位实际显示我们主题的项目。
关于android - 如何让 Espresso 点击特定的 RecyclerView item?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40366044/