3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

EspressoでSpinner内の特定の選択肢をクリックしたい

Posted at

tl;dr

Espresso recipes読もう。

単純な場合

例えばSpinnerの選択肢の「hoge」をクリックしたい場合、セオリー通りに書くなら次のような感じです。

onData(allOf(is(instanceOf(String.class)), is("hoge"))).perform(click());

AmbiguousViewMatcherExceptionとの戦い

普通はこれで全く問題ないのですが、どうしても同じ画面内に「hoge」を表示している個所が複数あってAmbiguousViewMatcherExceptionになってしまう場合があって頭を抱えました。

Matcher<String>とMatcher<View>を同居させることはできないので、「あるViewの子View」みたいな条件を増やすことはできません。

Spinnerをクリックした時のポップアップのView Herarchyを調べてみると次のような感じです。

View Hierarchy
+>PopupDecorView
|
+->PopupBackgroundView
|
+-->DropDownListView
|
+--->AppCompatCheckedTextView
|
+--->AppCompatCheckedTextView
|
+--->AppCompatCheckedTextView
|
以下略

ずらっと並んだAppCompatCheckedTextViewの中に目的の選択肢がありますので、以下のようなコードで叩くようにしました。

onView(allOf(withText("hoge"), withParent(withClassName(endsWith("ListView"))), withClassName(endsWith("TextView")))).perform(click());

すると、最初の方の選択肢だった場合は問題なくクリックできますが、選択肢がとても多いSpinnerだった場合は一定のインデックス(画面に完全に表示しきれていないもの)以後は以下のようなエラーになってしまいました。

Error performing 'single click' on view '(with text: is "hoge" and has parent matching: with class name: a string ending with "ListView" and with class name: a string ending with "TextView")'.

ViewActions.click()のドキュメントには「must be displayed on screen」とありますので、表示できていないViewで実行できないのは当然です。ここで単純にscrollTo()すればいいんじゃね?とやると「NoMatchingViewException: No views in hierarchy found matching」になります。PopupだからActivityのView Hierarchyにないからダメということでしょうか。

最早この時点で「画面に表示しきれないくらいのたくさんの選択肢をSpinnerに表示するんじゃない」と言われている気がします。とはいえ目の前に生きたプロダクトがありそいつに対してテストをしなくてはなりません。こういう時は困ったときのEspresso recipesです。Using inRoot to target non-default windowsというぴったりのものがありました。これを使って冒頭に書いたコードを直します。

onData(allOf(is(instanceOf(String.class)), is("hoge")))
  .inRoot(withDecorView(not(is(activityTestRule.getActivity().getWindow().getDecorView()))))
  .perform(click());

今度は問題なくすべてのテストが完遂しました。Spinnerに全く同じ選択肢が複数あることはあり得ないはずなのでこれでよさそうです。そもそもNoMatchingViewExceptionを吐いたときに「you may need to use Espresso.onData to load it from one of the following AdapterViews:android.widget.ListPopupWindow$DropDownListView{...」みたいな警告が出るのでonViewを使うのは筋悪でしょう。

回り道をしましたが、最初からレシピを読んでおけばよかっただけの話でした。

3
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?