各行に画像(R.id.row_image)とTextViewがあるRecyclerView(R.id.recyclerView)があります。最初の行の画像をクリックします。
onData(..)を使用しようとしましたが、機能していないようです。
RecyclerViewActions を使用します
onView(withId(R.id.recyclerView))
.perform(actionOnItemAtPosition(0, click()));
これをgradleスクリプトに含めます:
dependencies {
androidTestCompile 'com.Android.support.test:testing-support-lib:0.1'
androidTestCompile 'com.Android.support.test.espresso:espresso-core:2.0'
androidTestCompile 'com.Android.support.test.espresso:espresso-contrib:2.0'
}
Gaborの回答に追加するだけです(これはEspresso 2.0以降の正しい完全な回答です)。
espresso-contrib
およびRecyclerView
sを使用しているときに問題が発生する場合があります( Android-test-kit ticket を参照)。
回避策は、上記のespresso-contrib
依存関係Gaborにこの除外を追加することです。
androidTestCompile('com.Android.support.test.espresso:espresso-contrib:2.0') {
exclude group: 'com.Android.support', module: 'appcompat'
exclude group: 'com.Android.support', module: 'support-v4'
exclude module: 'recyclerview-v7'
}
(これはまだコメントを投稿する権利がないため、Gaborの回答に対するコメントではなく回答です)
Espresso 2.0がリリースされました。 変更ログ には以下が含まれます。
新機能
- エスプレッソ-contrib
- RecyclerViewActions:RecyclerViewsとの相互作用を処理します
私はまだこれを自分でテストしていませんが、トーマス・ケラー 投稿済み G +で、簡単な説明と、必要なビューマッチャーを含むGistへのリンクがあります。
新しい
RecyclerView
APIはViewGroup
ではなくAdapterView
から継承するため、EspressoのonData()
を使用してこのコンポーネントを使用してレイアウトをテストすることはできません。
要旨へのリンク 。
完全を期すために、コードを添付します(注:私のものではありません!すべてのクレジットはThomas Kellerにあります)
ViewMatcher:
public class ViewMatchers {
@SuppressWarnings("unchecked")
public static Matcher<View> withRecyclerView(@IdRes int viewId) {
return allOf(isAssignableFrom(RecyclerView.class), withId(viewId));
}
@SuppressWarnings("unchecked")
public static ViewInteraction onRecyclerItemView(@IdRes int identifyingView, Matcher<View> identifyingMatcher, Matcher<View> childMatcher) {
Matcher<View> itemView = allOf(withParent(withRecyclerView(R.id.start_grid)),
withChild(allOf(withId(identifyingView), identifyingMatcher)));
return Espresso.onView(allOf(isDescendantOfA(itemView), childMatcher));
}
}
そしてサンプル使用法:
onRecyclerItemView(R.id.item_title, withText("Test"), withId(R.id.item_content))
.matches(check(withText("Test Content")));
カスタムViewActionを使用する必要があります。
public void clickOnImageViewAtRow(int position) {
onView(withId(R.id.recycler_view)).perform(RecyclerViewActions.actionOnItemAtPosition(position, new ClickOnImageView()));
}
public class ClickOnImageView implements ViewAction{
ViewAction click = click();
@Override
public Matcher<View> getConstraints() {
return click.getConstraints();
}
@Override
public String getDescription() {
return " click on custom image view";
}
@Override
public void perform(UiController uiController, View view) {
click.perform(uiController, view.findViewById(R.id.imageView));
}
}
「testing-support-lib」も「espresso:espresso-core」も追加する必要はありません。 「espresso:espresso-contrib」が追加されると、それらは推移的に追加されます。
build.grade
dependencies {
androidTestCompile 'com.Android.support.test:runner:0.3'
androidTestCompile 'com.Android.support.test:rules:0.3'
androidTestCompile 'com.Android.support.test.espresso:espresso-contrib:2.2'
}
使用法:
onView(withId(R.id.recyclerView)).perform(
RecyclerViewActions.actionOnItemAtPosition(0, click()));
私は2つの方法を見つけました:
onView(allOf(withId(R.id.place_description),withText("what"))).perform(click());
`
public Matcher<View> withItemText(final String itemText) {
checkArgument(!TextUtils.isEmpty(itemText),"cannot be null");
return new TypeSafeMatcher<View>() {
@Override
protected boolean matchesSafely(View item) {
return allOf(isDescendantOfA(isAssignableFrom(RecyclerView.class)),withText(itemText)).matches(item);
}
@Override
public void describeTo(Description description) {
description.appendText("is descendant of a RecyclerView with text" + itemText);
}
};
}
`
そして、これを行います:
onView(withItemText("what")).perform(click());
私は@Gaborの答えに従いましたが、ライブラリを含めると、私はデックスの制限に達しました!
そのため、ライブラリを削除し、このgetInstrumentation().waitForIdleSync();
を追加してからonView(withId...))...
を呼び出しました
完全に動作します。
あなたの場合、同じIDを持つ複数の画像ビューがあるので、特定のリスト項目を選択する方法について何かを理解する必要があります。
here を投稿したように、カスタムRecyclerView
マッチャーを実装できます。 RecyclerView
があり、各要素が一致する主題を持っていると仮定しましょう:
public static Matcher<RecyclerView.ViewHolder> withItemSubject(final String subject) {
Checks.checkNotNull(subject);
return new BoundedMatcher<RecyclerView.ViewHolder, MyCustomViewHolder>(
MyCustomViewHolder.class) {
@Override
protected boolean matchesSafely(MyCustomViewHolder viewHolder) {
TextView subjectTextView = (TextView)viewHolder.itemView.findViewById(R.id.subject_text_view_id);
return ((subject.equals(subjectTextView.getText().toString())
&& (subjectTextView.getVisibility() == View.VISIBLE)));
}
@Override
public void describeTo(Description description) {
description.appendText("item with subject: " + subject);
}
};
}
そして使用法:
onView(withId(R.id.my_recycler_view_id)
.perform(RecyclerViewActions.actionOnHolderItem(withItemSubject("My subject"), click()));
基本的に、あなたはあなたが望むものにマッチすることができます。この例では、サブジェクトTextView
を使用しましたが、RecyclerView
アイテム内の任意の要素を使用できます。
もう1つ明確にする必要があるのは、可視性の確認(subjectTextView.getVisibility() == View.VISIBLE)
。 RecyclerView
内の他のビューも同じ件名を持つことができますが、View.GONE
。このようにして、カスタムマッチャーの複数の一致を回避し、実際に件名を表示するアイテムのみをターゲットにします。