android - 如何让 Espresso 点击特定的 RecyclerView item?

标签 android android-recyclerview android-espresso android-espresso-recorder

我正在尝试使用 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 项目。

最佳答案

您可以实现自定义 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/

相关文章:

android - espresso - 如何为自定义测试运行程序声明路径

java - 单击查看时从服务器检索数据

android - 每次更改设备方向时,项目都会添加到 Recycler View 中

android - 可以为两种 View 类型使用一个 viewholder 吗?

Android MediaCodec dequeueInputBuffer 总是返回 -1

android - Espresso如何测试Activity是否完成?

机器人 Espresso :test for new activity launch on button click is failing

android - 将 ListView 选择的文本传递给另一个 Activity

java - Android - 由 : java. security.cert.CertPathValidatorException 引起:未找到证书路径的信任 anchor

java - 页面转换器的 ViewPager 页面缩放问题