Espresso 在回收站视图中单击两个项目

时间:2021-01-29 20:12:05

标签: android android-recyclerview android-espresso

我想以这种方式在回收站视图的两个不同项目上执行两次点击:

onView(withId(R.id.recycler_view))
    .perform(
        RecyclerViewActions.actionOnItemAtPosition<CustomAdapter.CustomViewHolder>(
            1, 
            longClick()
        )
    )
onView(withId(R.id.recycler_view))
    .perform(
        RecyclerViewActions.actionOnItemAtPosition<CustomAdapter.CustomViewHolder>(
            2,
            longClick()
        )
    )

但我发现只有第二次点击位置为 2 的项目才真正执行。
我也尝试了另一种变体:

onView(withId(R.id.recycler_view))
    .perform(
        RecyclerViewActions.actionOnItemAtPosition<CustomAdapter.CustomViewHolder>(
            1,
            longClick()
        ),        
        RecyclerViewActions.actionOnItemAtPosition<CustomAdapter.CustomViewHolder>(
            2,
            longClick()
        )
    )

但结果是一样的 - 只执行了第二次点击。 所以,问题是,我缺少什么以及如何正确实施此案例?
感谢您的帮助!

更新。 似乎 initialTouchMode 标志不起作用。我用 initialTouchMode = true 初始化我的活动测试规则:

@get:Rule
var activityTestRule = ActivityTestRule(
        ListActivity::class.java,
        true,
        false
)

然后在每个@Test 方法中我调用 activityTestRule.launchActivity(Intent(Intent.ACTION_MAIN)) 然后我点击。我发现,只有第一次点击无效,但第二次和第三次点击有效。那么,这种行为的原因是什么?

1 个答案:

答案 0 :(得分:0)

我找到了问题的原因。我的回收视图项中有布局内部的视图。该视图实现了加载一些 Markdown 文本的 WebView。加载需要一些时间,所以我的点击是更早执行的,然后才真正呈现视图。这是使测试工作的代码示例:

function hasMoreTrue(arr) {
  for (let i = 0; i < arr.length; i++) {
    if (arr[i] === true) {
      return true;
    } else {
      return false;
    }
  }
}

console.log(hasMoreTrue([true, true, false])); // true
console.log(hasMoreTrue([true, false, true, false])); // true
console.log(hasMoreTrue([true, false, false, false])); // false
console.log(hasMoreTrue([false])); // false

其中 waitForMillis() 是自定义操作

onView(withId(R.id.recycler_view))
                .perform(
                        waitForMillis(1500),//wait until markdown views loaded
                        actionOnItemAtPosition<CustomAdapter.CustomViewHolder>(1, longClick()),
                        actionOnItemAtPosition<CustomAdapter.CustomViewHolder>(2, longClick())
                )

这个解决方案有缺点。为了确保在单击之前渲染视图,您需要设置固定时间,这可能比渲染真正需要的时间更长。所以最好的解决方案是自定义匹配器,但我现在没有准备好的例子。

相关问题