RecyclerView无法在Android espresso测试上滚动

时间:2019-07-26 16:23:46

标签: android kotlin android-recyclerview automated-tests android-espresso

我想滚动一个recyclerView并单击一个最初在屏幕上不可见的项目,但使用Espresso,但是滚动操作不起作用(在其他活动中的其他recyclerViews的其他测试中也是如此)。

我尝试了https://developer.android.com/training/testing/espresso/lists中指示的onData()方法

,但效果不佳。

这是我执行滚动并单击的方法:

fun scrollToPositionAndClick(resId: Int, position: Int) {
        getActivityInstance()?.findViewById<RecyclerView>(resId)?.adapter?.let {
            onView(withId(resId))
                .perform(
                    scrollToPosition<RecyclerView.ViewHolder>(position),
                    actionOnItemAtPosition<RecyclerView.ViewHolder>(position, click())
                )
        }
    }

此方法可在其他活动测试中使用,但由于某种原因,该方法不适用于此屏幕(碎片),并且出现此错误:

androidx.test.espresso.PerformException: Error performing 'single click - At Coordinates: 290, 2197 and precision: 16, 16'
...
Caused by: androidx.test.espresso.PerformException: Error performing 'click (after 3 attempts)' on view 'unknown'.

1 个答案:

答案 0 :(得分:0)

当ViewPager中有RecyclerView时,我没有滚动问题。我能够通过自己执行RecyclerViewAction.scrollToPosition来修复它。我没有使用recyclerView滚动条的API,而是使用LayoutManager的API,如果它是LinearLayoutManager,则使用了scrollToPositionWithOffset。

这是操作的代码。除了perform方法

以外,其他所有内容都与原始内容相同
public final class CustomRecyclerViewActions {

private CustomRecyclerViewActions() { }


public static <VH extends RecyclerView.ViewHolder> ViewAction scrollToPosition(@IntRange(from = 0) final int position) {
   return new ScrollToPositionViewAction(position);
}

private static final class ScrollToPositionViewAction implements ViewAction {
   private final int position;

   private ScrollToPositionViewAction(int position) {
     this.position = position;
   }

   public Matcher<View> getConstraints() {
      return Matchers.allOf(ViewMatchers.isAssignableFrom(RecyclerView.class), ViewMatchers.isDisplayed());
   }

  public String getDescription() {
    int var1 = this.position;
    return (new StringBuilder(44)).append("scroll RecyclerView to position: ").append(var1).toString();
  }

  public void perform(@NonNull UiController uiController, @NonNull View view) {
    RecyclerView recyclerView = (RecyclerView)view;
    RecyclerView.LayoutManager layoutManager = recyclerView.getLayoutManager();
    if (layoutManager instanceof LinearLayoutManager) {
      ((LinearLayoutManager) layoutManager).scrollToPositionWithOffset(this.position, 0);
    } else {
      layoutManager.scrollToPosition(this.position);
    }
    uiController.loopMainThreadUntilIdle();
   }
 }
}