1

RecyclerViewを使用しているAndroidアプリのエスプレッソで計測テストを書こうとしています。ここでは主なレイアウトは次のとおりです。Espressoが特定のRecyclerViewアイテムをクリックする方法を教えてください。

<?xml version="1.0" encoding="utf-8"?> 
<android.support.design.widget.CoordinatorLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    xmlns:app="http://schemas.android.com/apk/res-auto" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <android.support.v7.widget.RecyclerView 
     android:id="@+id/grid" 
     android:layout_width="match_parent" 
     android:layout_height="match_parent" 
     app:layout_behavior="@string/appbar_scrolling_view_behavior"/> 

</android.support.design.widget.CoordinatorLayout> 

...とアイテムビューのレイアウト:

<?xml version="1.0" encoding="utf-8"?> 
<RelativeLayout 
    xmlns:android="http://schemas.android.com/apk/res/android" 
    android:layout_width="match_parent" 
    android:layout_height="match_parent"> 

    <TextView 
     android:id="@+id/label" 
     android:layout_width="match_parent" 
     android:layout_height="wrap_content"/> 

</RelativeLayout> 

これは全label IDを持って、画面上のTextViewsのカップルがあることを意味します。特定のラベルをクリックしようとしています。私はエスプレッソテストレコーダーを聞かせしようとしたコードを生成します。

onView(allOf(withId(R.id.grid), isDisplayed())) 
    .perform(actionOnItemAtPosition(5, click())); 

私はむしろのようなものにしたい:

// Not working 
onView(allOf(withId(R.id.grid), isDisplayed())) 
    .perform(actionOnItem(withText("Foobar"), click())); 

リーディング

私は、トピックについてかなり読んでますがその内容に基づいてRecyclerViewアイテムをテストする方法を把握することはできませんその位置インデックスに基づいて。

答えて

1

actionOnItem()マッチViewHolderのこの場合、TextViewはRelativeLayoutにラップされているため、Matcherを更新してそれを考慮する必要があります。

onView(allOf(withId(R.id.grid), isDisplayed())) 
    .perform(actionOnItem(withChild(withText("Foobar")), click())); 

また、あなたのマッチャがより複雑なネスティングの場合でラップするhasDescendant()を使用することができます。

+0

'hasDescendant()'は、深度ビューがネストされているかどうかにかかわらず、階層レベルを自動的に走査しますか?あるいは、 'hasDescendant(hasDescendant(...))'を使う必要がありますか? – JJD

+0

うん、 'hasDescendant()'は 'onView()'部分にあるルートからビュー階層全体を扱います。 recyclerviewアクションの場合、ルートは 'itemView'です。 –

3

カスタム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())); 

基本的にあなたが欲しいものを一致させることができるのは、あなたが各要素は、あなたが一致wonna対象持つRecyclerViewを持っていると仮定しましょう。この例では、サブジェクトTextViewを使用しましたが、RecyclerViewアイテム内の任意のエレメントにすることができます。

明確にするもう1つのことは、視認性を確認することです(subjectTextView.getVisibility() == View.VISIBLE)RecyclerView内の他のビューに同じ件名があることがありますが、それはView.GONEとなることがあります。こうすることで、カスタムマッチャーの複数のマッチを避け、実際にテーマを表示するアイテムのみをターゲットにします。

+0

appendTextの機能は何ですか? – Richardweber32

+1

このようにして、エラーが発生した場合のエラーの説明をカスタマイズできます。 – denys

関連する問題