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

dam*_*son 29 android ui-testing android-viewpager android-espresso

我有一个ViewPager只包含图片和按钮的项目.

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

我试图只选择一个有位置的项目:

onData(is(instanceOf(ItemClass.class)))
            .atPosition(0)
            .onChildView(withId(R.id.button))
            .perform(click());
Run Code Online (Sandbox Code Playgroud)

造成:

NoMatchingViewException:层次结构中找不到匹配的视图:可从类中分配:class android.widget.AdapterView

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

dam*_*son 87

FirstVal,ViewPager不是AdapterView,它直接延伸ViewGroup.所以该方法onData() 不能用于ViewPager.

1.解决方案

因为它是一个ViewGroup,每个项目都是它的直接孩子ViewPager.因此,该过程是使用自定义匹配器(如此一个firstChildOf())引用第一个视图子进程,并使用hasDescendant()isDescendantOfA()访问目标视图并对其执行操作.

 onView(allOf(withId(R.id.button), isDescendantOfA(firstChildOf(withId(R.id.viewpager)))))
            .perform(click());
Run Code Online (Sandbox Code Playgroud)

2.解决方案(最佳)

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

onView(allOf(withId(R.id.button), isDisplayed())).perform(click());
Run Code Online (Sandbox Code Playgroud)

就如此容易.

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

onView(withId(R.id.viewpager)).perform(swipeLeft());
Run Code Online (Sandbox Code Playgroud)

  • 您可能想使用`isCompletelyDisplayed()`.根据我的经验,`isDisplayed()`也匹配屏幕外页面中的视图. (12认同)
  • 我在使用相同视图但具有不同项目的 ViewPager 上遇到了类似的问题。@TWiStErRob 提到 ```isDisplayed()``` 匹配离屏视图。所以我尝试了 ```isCompletelyDisplayed()``` 但是当我在检查前刷卡时,即使关闭了动画,Espresso 似乎也无法做到这一点。所以我最终做的是使用:```onView(allOf(withId(R.id.recyclerView), isDisplayingAtLeast(60)))``` 现在一直正确识别回收站视图。 (2认同)