ViewPager中的Espresso Recylerview匹配多个视图

时间:2016-10-11 13:03:50

标签: android android-fragments android-recyclerview android-espresso

如何使用实现具有匹配多个视图的ID的RecylerView的片段来定位Viewpager?

我有一个拥有Viewpager的MainActivity。 Viewpager有5个标签。在这5个标签中,我使用RecylerViews在每个标签中加载图像。

RecylerView XML在不同的片段中重复使用,因此当使用Espresso访问它时,它会让抱怨ID与多个视图匹配。

<android.support.v7.widget.RecyclerView
    xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/recycler_view"
    android:layout_width="match_parent"
    android:layout_height="match_parent"/>

我的RecylerView不会加载任何文字,只会加载图片,因此我甚至无法进行withText("Text here")。我不能将onData()用于RecylerViews。

@RunWith(AndroidJUnit4.class)
@LargeTest
public class ExampleTest {

    @Rule
    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(
            MainActivity.class);

    Activity activity = mActivityRule.getActivity();

    @Test
    public void ExampleMethod() {

        // perform a swipe
        onView(withId(R.id.viewpager)).perform(swipeLeft());  

       // try to click on one of the recycler view items.
       // this crashes:
       onView(withId(R.id.recycler_view))
           .perform(RecyclerViewActions.actionOnItemAtPosition(2, click()));

    }
}

因此它崩溃并指出错误

  

android.support.test.espresso.AmbiguousViewMatcherException:&#39; id:com.example.app:id / recycler_view&#39;匹配层次结构中的多个视图。       问题观点标有&#39; **** MATCHES ****&#39;下方。

//列出不同的层次结构

View Hierarchy:

View Hierarchy:
+>DecorView{id=-1, visibility=VISIBLE, width=720, height=1280, 
  has-focus=false, has-focusable=true, has-window-focus=true, 
  is-clickable=false, is-enabled=true, is-focused=false, 
  is-focusable=false, is-layout-requested=false, is-selected=false, 
  root-is-layout-requested=false, has-input-connection=false, x=0.0, 
  y=0.0, child-count=1}

//...

3 个答案:

答案 0 :(得分:14)

我在使用ViewPager时遇到了同样的问题,并将isDisplayed()子句添加到ViewMatcher为我解决了这个问题(不过,与Espresso中的所有内容一样,它可以是有时片状......)

onView(allof(isDisplayed(), withId(R.id.recycler_view)))
    .perform(RecyclerViewActions.actionOnItemAtPosition(2, click()));

答案 1 :(得分:1)

我已经通过一种变通办法解决了这一问题,即唯一实际可见的项目的宽度和高度与在相应布局中指定的值完全匹配。所有其他视图分页器项均具有默认尺寸。

所以我创建了一个简单的匹配器:

private val sizeMatcher = object : TypeSafeMatcher<View>(){
    override fun describeTo(description: Description?) {
        description?.appendText("with expected size")
    }
    override fun matchesSafely(item: View?): Boolean {
        return item != null && (item.height > DEFAULT_HEIGHT || item.width > DEFAULT_WIDTH)
    } 
}

不同视图的默认值可能会有所不同

接下来,我在匹配表达式中添加了此匹配器:

fun checkDisplayed(viewId: Int) {
    Espresso.onView(Matchers.allOf(ViewMatchers.withId(viewId), ViewMatchers.isDisplayingAtLeast(80), sizeMatcher)).check(ViewAssertions.matches(ViewMatchers.isDisplayingAtLeast(80)))
}

显示阈值很小(80),可以通过视图传呼器刚刚滑过而Espresso不等待它将视图滚动到屏幕边框并完整显示的情况

答案 2 :(得分:0)

我做的是为每个片段设置不同的内容说明,Espresso支持hasContentDescription()withContentDescription() ......