使用 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
我有一个 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