如何检查特定RecyclerView项目上的视图是否可见?

Neo*_*rge 4 android unit-testing android-espresso

我刚开始使用浓缩咖啡。我实际上无法使用此代码获得要测试的内容:

    onData(withId(R.id.relativelayout_tag))
        .inAdapterView(withId(R.id.recyclerview_tag_list))
        .onChildView(withId(R.id.imageview_tag))
        .atPosition(1)
        .check(matches(isDisplayed()));
Run Code Online (Sandbox Code Playgroud)

R.id.imageview_tag的孩子在哪里R.id.relativelayout_tagR.id.relativelayout_tag保留了我的适配器项目的全部内容。R.id.recyclerview_tag_list是我RecyclerView为其分配特定姓名的名字RecyclerView Adapter

这是非常非常基本的测试。以下是用户过程:

  1. 选择特定的,第一项RecyclerView(我不太在乎视图中的文本)。也不要建议使用视图文本来标识第一项。我不关心适配器项目的内容,甚至不在某个视图上放置唯一标签。
  2. 选择后,应显示指示器视图(一个ImageView,显示已选中该项目)。

非常基本和简单。使用Espresso为这个基本的用户故事编写测试非常困难。当我运行该特定测试时,它总是无法说明:

Caused by: java.lang.RuntimeException: Action will not be performed because the target view does not match one or more of the following constraints:
(is assignable from class: class android.widget.AdapterView and is displayed on the screen to the user)
Target view: "RecyclerView{id=2131624115, res-name=recyclerview_tag_list, visibility=VISIBLE, width=480, height=1032, has-focus=false, has-focusable=true, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=true, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0, child-count=15}"
Run Code Online (Sandbox Code Playgroud)

因为列表已经可见,所以没有意义。我什至可以运行此测试:

    onView(withId(R.id.recyclerview_tag_list))
            .perform(RecyclerViewActions
            .actionOnItemAtPosition(1, click()));
Run Code Online (Sandbox Code Playgroud)

这是完整的测试:

@Test
public void shouldTagToggleSelected()
{
    onView(withId(R.id.recyclerview_tag_list))
            .perform(RecyclerViewActions
            .actionOnItemAtPosition(1, click()));

    onData(withId(R.id.relativelayout_tag))
        .inAdapterView(withId(R.id.recyclerview_tag_list))
        .onChildView(withId(R.id.imageview_tag))
        .atPosition(1)
        .check(matches(isDisplayed()));

    //onView(withId(R.id.imageview_tag))
    //        .check(matches(isDisplayed()));
}
Run Code Online (Sandbox Code Playgroud)

我要测试的指标指示器视图是否visible 仅在该特定项目(或我选择的任何项目)设置了可见性。

有什么想法吗?也许我错过了很多东西。

非常感谢!

Be_*_*ive 11

onData不能使用,RecyclerView因为RecyclerView不能扩展AdapterView

您需要使用onView来声明。如果它是“回收者”视图中的第一项,则可以使用类似该匹配器的内容来声明:

public static Matcher<View> withViewAtPosition(final int position, final Matcher<View> itemMatcher) {
        return new BoundedMatcher<View, RecyclerView>(RecyclerView.class) {
            @Override
            public void describeTo(Description description) {
                itemMatcher.describeTo(description);
            }

            @Override
            protected boolean matchesSafely(RecyclerView recyclerView) {
                final RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(position);
                return viewHolder != null && itemMatcher.matches(viewHolder.itemView);
            }
        };
}
Run Code Online (Sandbox Code Playgroud)

用法如下:

    onView(withId(R.id.recyclerview_tag_list))
            .check(matches(withViewAtPosition(1, hasDescendant(allOf(withId(R.id.imageview_tag), isDisplayed())))));
Run Code Online (Sandbox Code Playgroud)

请记住,如果尚未布置您的ViewHolder,则该匹配器将失败。如果是这种情况,则需要使用RecyclerViewActions滚动到ViewHolder 。如果您在使用匹配器之前单击测试中的项目,则无需滚动。