私はespresso-contribを使用してRecyclerView
でアクションを実行しています。
onView(withId(R.id.recycler_view))
.perform(RecyclerViewActions.actionOnItemAtPosition(0, click())); //click on first item
そして、私はそれについてアサーションを実行する必要があります。このようなもの:
onView(withId(R.id.recycler_view))
.perform(RecyclerViewActions.actionOnItemAtPosition(0, check(matches(withText("Test Text"))));
しかし、 RecyclerViewActions はもちろんアクションを予期しているため、誤った2番目の引数タイプを示しています。 espresso-contribにはRecyclerViewAssertions
はありません。
リサイクラービューでアサーションを実行する方法はありますか?
Danny Roaのソリューションを確認する必要があります Custom RecyclerView Actions そして、次のように使用します。
onView(withRecyclerView(R.id.recycler_view)
.atPositionOnView(1, R.id.ofElementYouWantToCheck))
.check(matches(withText("Test text")));
とても簡単。追加のライブラリは必要ありません。行う:
_ onView(withId(R.id.recycler_view))
.check(matches(atPosition(0, withText("Test Text"))));
_
viewHolderがViewGroupを使用している場合、withText()
を次のようなhasDescendant()
でラップします。
_onView(withId(R.id.recycler_view))
.check(matches(atPosition(0, hasDescendant(withText("Test Text")))));
_
メソッドを使用すると、Utils
クラスに入れることができます。
_public static Matcher<View> atPosition(final int position, @NonNull final Matcher<View> itemMatcher) {
checkNotNull(itemMatcher);
return new BoundedMatcher<View, RecyclerView>(RecyclerView.class) {
@Override
public void describeTo(Description description) {
description.appendText("has item at position " + position + ": ");
itemMatcher.describeTo(description);
}
@Override
protected boolean matchesSafely(final RecyclerView view) {
RecyclerView.ViewHolder viewHolder = view.findViewHolderForAdapterPosition(position);
if (viewHolder == null) {
// has no item on such position
return false;
}
return itemMatcher.matches(viewHolder.itemView);
}
};
}
_
最初にアイテムが画面に表示されない場合は、前にスクロールしてください:
_ onView(withId(R.id.recycler_view))
.perform(scrollToPosition(87))
.check(matches(atPosition(87, withText("Test Text"))));
_
Riwnodennykの答えを高めるために、ViewHolder
がViewGroup
のような直接View
オブジェクトではなくTextView
である場合、hasDescendant
マッチャーを追加して、 TextView
内のViewGroup
オブジェクト。例:
onView(withId(R.id.recycler_view))
.check(matches(atPosition(0, hasDescendant(withText("First Element")))));
私の場合、Danny Roaとriwnodennykのソリューションをマージする必要がありました。
onView(withId(R.id.recyclerview))
.perform(RecyclerViewActions.scrollToPosition(80))
.check(matches(atPositionOnView(80, withText("Test Test"), R.id.targetview)));
およびメソッド:
public static Matcher<View> atPositionOnView(final int position, final Matcher<View> itemMatcher,
@NonNull final int targetViewId) {
return new BoundedMatcher<View, RecyclerView>(RecyclerView.class) {
@Override
public void describeTo(Description description) {
description.appendText("has view id " + itemMatcher + " at position " + position);
}
@Override
public boolean matchesSafely(final RecyclerView recyclerView) {
RecyclerView.ViewHolder viewHolder = recyclerView.findViewHolderForAdapterPosition(position);
View targetView = viewHolder.itemView.findViewById(targetViewId);
return itemMatcher.matches(targetView);
}
};
}
私は同じ問題に苦労しており、6つのアイテムを持つリサイクラービューがあり、5番目のアイテムを選択しなければならず、5番目のビューはビューに表示されません。
上記のソリューションも機能します。また、少し遅れていることは知っていますが、共有する価値があると思いました。
以下の簡単なソリューションでこれを行いました:
onView(withId(R.id.recylcer_view))
.perform(RecyclerViewActions.actionOnItem(
hasDescendant(withText("Text of item you want to scroll to")),
click()));
RecyclerViewActions.actionOnItem
-ViewAction
と一致するビューでviewHolderMatcher
を実行します。
RecyclerView
に一致するビューまでitemViewMatcher
をスクロールします詳細については、以下を参照してください。 RecyclerViewActions.actionOnItem
Danny Roaのソリューションは素晴らしいですが、スクロールしたばかりのオフスクリーンアイテムでは機能しませんでした。修正によりこれが置き換えられます。
View targetView = recyclerView.getChildAt(this.position)
.findViewById(this.viewId);
これとともに:
View targetView = recyclerView.findViewHolderForAdapterPosition(this.position)
.itemView.findViewById(this.viewId);
... TestUtils
クラス で。
このスレッドはかなり古いものですが、私は最近、RecyclerViewActionサポートをアサーションにも使用できるように拡張しました。これにより、ビューマッチャーを使用しながら、位置を指定せずに画面外の要素をテストできます。
この記事をご覧ください> Better Android RecyclerView Testing !