Help us understand the problem. What is going on with this article?

EspressoでcheckableなMenuItemのテスト

More than 3 years have passed since last update.

タイトルの通り、オプションメニューにあるcheckableなMenuItemのテストをしたくて、こんな投稿をしました。

http://ja.stackoverflow.com/questions/25324/espresso%E3%81%A7checkable%E3%81%AAmenuitem%E3%81%AE%E3%83%86%E3%82%B9%E3%83%88

が、回答が付かず・・・
まあ英語で使ってなんぼですよね、Stack Overflowは。
で、結局いろいろ試行錯誤して、質問にも載せたViewの階層状態を参考にして、次のようにMatcherを作りました。
Matcherを作るのには全然馴れていないので、かなり四苦八苦しましたが、見た感じ意図したとおりに動作しているようです。

やっていることは、Checkboxクラスのオブジェクトを全部受け取って、その親Viewが持つ子Viewの中からTextViewを探して、そいつが指定したタイトル文字列を持っているかチェックしています。
階層状態が見えたから書けた愚直な手法ですね。
OSのバージョンが違ったらもしかしたらアウトかも知れませんが、support-libraryを使っている間は大丈夫な気がします・・・が、何も保証は出来ません。

EspressoUtil.java
    public static MenuItemTitleMatcher withCheckBoxTitle(final String title) {
        return new MenuItemTitleMatcher(title);
    }

    public static class MenuItemTitleMatcher extends BaseMatcher<Object> {
        private final String title;

        public MenuItemTitleMatcher(String title) {
            this.title = title;
        }

        TextView getChildTextView(ViewGroup view, String title) {
            int num = view.getChildCount();
            for (int i = 0; i < num; i++) {
                View child = view.getChildAt(i);
                if (child instanceof TextView) {
                    if (title.equals(((TextView) child).getText())) {
                        return (TextView) child;
                    }
                }
            }
            return null;
        }

        @Override
        public boolean matches(Object o) {
            if (o instanceof CheckBox) {
                CheckBox checkbox = (CheckBox) o;
                ViewParent parent = checkbox.getParent();
                if (parent instanceof ListMenuItemView) {
                    // 子のViewGroupからTextViewを探す
                    int num = ((ListMenuItemView) parent).getChildCount();
                    for (int i = 0; i < num; i++) {
                        View child = ((ListMenuItemView) parent).getChildAt(i);
                        if (child == o) continue;
                        if (child instanceof ViewGroup) {
                            TextView textView = getChildTextView((ViewGroup) child, title);
                            if (textView != null)
                                return true;
                        }
                    }
                }
                return false;
            }
            return false;
        }

        @Override
        public void describeTo(Description description) {
            description.appendText("expected with Title: ");
            description.appendText("" + title);
        }
    }

使い方

onView(allOf(withClassName(endsWith("CheckBox")),
                EspressoUtil.withCheckBoxTitle(getString(R.string.action_lock))))
                .check(matches(isNotChecked()))
                .perform(click());
kasa_le
言語経験はC→C++→Java+Android(たまにiOS/swift経験なし)→Kotlin Flutterも良いよ. 独学でPHPとpython
Leading-Edge
ITエンジニアの生涯価値向上を目指し、派遣・紹介・教育・自社開発など様々な分野から全方位支援を行っております。
https://www.leadinge.co.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away