使用 Espresso 测试 ViewPager。如何对项目的按钮执行操作?

Testing ViewPager with Espresso. How perfom action to a button of an Item?

我有一个 ViewPager 项目,其中仅包含一张图片和一个按钮。

我无法与项目(页面)的 UI 成功交互,因为除了显示的图片外,没有任何东西可以区分(从 UI 的角度来看)的所有项目ViewPager.

我试过 select 只有一个位置的项目:

onData(is(instanceOf(ItemClass.class)))
            .atPosition(0)
            .onChildView(withId(R.id.button))
            .perform(click());

导致:

NoMatchingViewException: No views in hierarchy found matching: is assignable from class: class android.widget.AdapterView

如何使用 Espresso 访问和测试 ViewPager 的项目?

FirstVal,ViewPager 不是AdapterView,它直接扩展自ViewGroup。所以方法 onData() 不能 用于 ViewPager.

解决方案 1

因为它是 ViewGroup,每个项目都是其 ViewPager 的直接子项。 所以这个过程是使用自定义匹配器引用第一个视图子视图(像这个firstChildOf()) and playing with hasDescendant() and isDescendantOfA()来访问目标视图并对其执行操作。

 onView(allOf(withId(R.id.button), isDescendantOfA(firstChildOf(withId(R.id.viewpager)))))
            .perform(click());

解决方案 2(最佳)

由于 ViewPager 的特殊性是逐个显示组成它的每个项目(#1 解决方案的子视图)(逐页样式)。因此,即使您的项目使用具有相同 ID 的相同布局,也只会显示一个。所以我们可以通过它的 Id 引用目标视图并添加约束 isDisplayed()。它只会匹配一个视图,即当前显示的那个。

onView(allOf(withId(R.id.button), isDisplayed())).perform(click());

就这么简单。

如果您想要另一个项目,您可以在 ViewPager 上执行 swipe() 以更改显示的项目:

onView(withId(R.id.viewpager)).perform(swipeLeft());

来自 Android dev doc 的注释:

isDisplayed will select views that are partially displayed (eg: the full height/width of the view is greater than the height/width of the visible rectangle). If you wish to ensure the entire rectangle this view draws is displayed to the user use isCompletelyDisplayed()

感谢@TWiStErRob