我想以这种方式在回收站视图的两个不同项目上执行两次点击:
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)) 然后我点击。我发现,只有第一次点击无效,但第二次和第三次点击有效。那么,这种行为的原因是什么?
答案 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())
)
这个解决方案有缺点。为了确保在单击之前渲染视图,您需要设置固定时间,这可能比渲染真正需要的时间更长。所以最好的解决方案是自定义匹配器,但我现在没有准备好的例子。