web-dev-qa-db-ja.com

Espressoを使用してインデックスで子ビューを選択する

Espressoで子画像ビューでカスタムウィジェットビューを使用する場合、n番目の子を選択するためにどのMatcherタイプを使用できますか?例:

+--------->NumberSlider{id=2131296844, res-name=number_slider, visibility=VISIBLE, width=700, height=95, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=false, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=10.0, y=0.0, child-count=7}
|
+---------->NumberView{id=-1, visibility=VISIBLE, width=99, height=95, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=0.0, y=0.0}
|
+---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=99.0, y=0.0}
|
+---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=199.0, y=0.0}
|
+---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=299.0, y=0.0}
|
+---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=399.0, y=0.0}
|
+---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=499.0, y=0.0}
|
+---------->NumberView{id=-1, visibility=VISIBLE, width=100, height=95, has-focus=false, has-focusable=false, has-window-focus=true, is-clickable=true, is-enabled=true, is-focused=false, is-focusable=false, is-layout-requested=false, is-selected=false, root-is-layout-requested=false, has-input-connection=false, x=599.0, y=0.0}
30
ijunes
 public static Matcher<View> nthChildOf(final Matcher<View> parentMatcher, final int childPosition) {
    return new TypeSafeMatcher<View>() {
      @Override
      public void describeTo(Description description) {
        description.appendText("with "+childPosition+" child view of type parentMatcher");
      }

      @Override
      public boolean matchesSafely(View view) {
        if (!(view.getParent() instanceof ViewGroup)) {
          return parentMatcher.matches(view.getParent());
        }

        ViewGroup group = (ViewGroup) view.getParent();
        return parentMatcher.matches(view.getParent()) && group.getChildAt(childPosition).equals(view);
      }
    };
  }

それを使用するには

onView(nthChildOf(withId(R.id.parent_container), 0)).check(matches(withText("I am the first child")));
60
Maragues

Maraguesのソリューションを少し改善するために、いくつかの変更を加えました。

解決策は、親ビューの別のMatcher <View>をラップするカスタムMatcher <View>を作成し、一致する子ビューのインデックス。

public static Matcher<View> nthChildOf(final Matcher<View> parentMatcher, final int childPosition) {
    return new TypeSafeMatcher<View>() {
        @Override
        public void describeTo(Description description) {
            description.appendText("position " + childPosition + " of parent ");
            parentMatcher.describeTo(description);
        }

        @Override
        public boolean matchesSafely(View view) {
            if (!(view.getParent() instanceof ViewGroup)) return false;
            ViewGroup parent = (ViewGroup) view.getParent();

            return parentMatcher.matches(parent)
                    && parent.getChildCount() > childPosition
                    && parent.getChildAt(childPosition).equals(view);
        }
    };
}

詳細な説明

description引数に追加することで、マッチャーのわかりやすい説明を提供するために、describeToメソッドをオーバーライドできます。また、describeTo呼び出しを親マッチャーに伝達して、説明も追加されるようにすることもできます。

@Override
public void describeTo(Description description) {
    description.appendText("position " + childPosition + " of parent "); // Add this matcher's description.
    parentMatcher.describeTo(description); // Add the parentMatcher description.
}

次に、matchesSafelyをオーバーライドする必要があります。これにより、ビュー階層内で一致が見つかったタイミングが決まります。指定された親マッチャーと親が一致するビューで呼び出された場合、指定された位置でビューが子と等しいことを確認します。

親にchildCountが子の位置より大きい場合、getChildAtはnullを返し、テストをクラッシュさせます。適切なテストレポートとエラーメッセージを取得するために、クラッシュを回避し、テストが失敗するようにすることをお勧めします。

@Override
public boolean matchesSafely(View view) {
if (!(view.getParent() instanceof ViewGroup)) return false; // If it's not a ViewGroup we know it doesn't match.
    ViewGroup parent = (ViewGroup) view.getParent();

    return parentMatcher.matches(parent) // Check that the parent matches.
            && parent.getChildCount() > childPosition // Make sure there's enough children.
            && parent.getChildAt(childPosition).equals(view); // Check that this is the right child.
}
22
eski

親ビューを取得できる場合。 このリンク の場合、ビューの最初の子を取得するためのマッチャーが定義されているため、手がかりが得られます。

     public static Matcher<View> firstChildOf(final Matcher<View> parentMatcher) {
        return new TypeSafeMatcher<View>() {
            @Override
            public void describeTo(Description description) {
                description.appendText("with first child view of type parentMatcher");
            }

            @Override
            public boolean matchesSafely(View view) {       

                if (!(view.getParent() instanceof ViewGroup)) {
                    return parentMatcher.matches(view.getParent());                   
                }
                ViewGroup group = (ViewGroup) view.getParent();
                return parentMatcher.matches(view.getParent()) && group.getChildAt(0).equals(view);

            }
        };
    }
11
Nick Dong