Slide 1

Slide 1 text

⽣まれ変わったUI Automator を使いこなす 2016.2.19 @sumio_tym (TOYAMA Sumio) 1 DroidKaigi 2016

Slide 2

Slide 2 text

⾃⼰紹介 • ⽒名: 外⼭ 純⽣ (TOYAMA Sumio) @sumio_tym (Twitter) / @sumio (GitHub) • 所属: NTTソフトウェア株式会社 • 業務内容: 社内Android関連プロジェクトの技術⽀援 • プライベート: •  STAR(テスト⾃動化研究会) •  @IT連載「スマホ向け無料システムテスト⾃動化ツール」 uiautomator/Appiumの回を書きました http://www.atmarkit.co.jp/ait/kw/smapho_testtool.html 2

Slide 3

Slide 3 text

お話しすること • 新しくなった⾃動テストツールUI Automator 2 について説明します •  旧版(uiautomator)との違い •  APIの基本的な使い⽅ •  Tips •  UI Automater2の使いどころ 3 とにかく情報が少ない

Slide 4

Slide 4 text

話の流れ 1.  概要 2.  基本的な使い⽅ •  準備 •  UI部品の検索と操作 •  待ち合わせ 3.  Tips 4.  UI Automator2の使いどころ 5.  まとめ 4

Slide 5

Slide 5 text

1.  概要 2.  基本的な使い⽅ •  準備 •  UI部品の検索と操作 •  待ち合わせ 3.  Tips 4.  UI Automator2の使いどころ 5.  まとめ 5

Slide 6

Slide 6 text

UI Automator2の概要 • Android SDK標準のテストツール http://goo.gl/E5DH9y (developer.android.com) • 特徴 •  ブラックボックステスト向け •  複数アプリにまたがったテスト(操作)ができる (ソースやapkが⼿元に無くてもテストできる) • ソースコードリポジトリ https://goo.gl/ONClV1 (android.googlesource.com) ※旧uiautomatorからリポジトリの場所が移動しているので注意 • APIリファレンス http://goo.gl/alp382 (android.googlesource.com) 6

Slide 7

Slide 7 text

旧uiautomatorとの違い 旧uiautomator UI Automator2 UI Automator2 対応APIレベル 16以上 18, 19 21以上 IDE/ビルドツール Eclipse/ant Android Studio/Gradle 実⾏⽅法 uiautomator コマンド Instrumentation Test テキスト⼊⼒ ASCIIのみ Unicode パフォーマンス やや遅い 速い 旧APIの利⽤ ○ △ ○ 新APIの利⽤ × △ ○ 7 おすすめ! 詳しくは https://goo.gl/mTP8ig 参照

Slide 8

Slide 8 text

1.  概要 2.  基本的な使い⽅ •  準備 •  UI部品の検索と操作 •  待ち合わせ 3.  Tips 4.  UI Automator2の使いどころ 5.  まとめ 8

Slide 9

Slide 9 text

準備: ファイル配置とbuild.gradle 9 EFQFOEFODJFT\ BOESPJE5FTU$PNQJMFDPNBOESPJETVQQPSUUFTUSVOOFS BOESPJE5FTU$PNQJMFDPNBOESPJETVQQPSUUFTUSVMFT BOESPJE5FTU$PNQJMF= DPNBOESPJETVQQPSUUFTUVJBVUPNBUPSVJBVUPNBUPSW ^ for Instrumentation Test for UI Automator2 •  テストコード格納先 .0%6-&@%*3TSDBOESPJE5FTU •  CVJMEHSBEMF

Slide 10

Slide 10 text

準備: 初期化 10 !3VO8JUI "OESPJE+6OJUDMBTT QVCMJDDMBTT.Z6JBVUPNBUPS5FTU\ !3VMF QVCMJD"DUJWJUZ5FTU3VMFBDUJWJUZ5FTU3VMF QSJWBUF6J%FWJDFVJ%FWJDF !#FGPSF QVCMJDWPJETFU6Q UISPXT&YDFQUJPO\ VJ%FWJDF6J%FWJDF HFU*OTUBODF *OTUSVNFOUBUJPO3FHJTUSZ HFU*OTUSVNFOUBUJPO ^ ^ 6J%FWJDFを初期化しておく

Slide 11

Slide 11 text

準備: まとめ • 基本的な考え⽅は Instrumentation Test (Espressoなど)と同じ • TFU6Q で6J%FWJDFの初期化を忘れずに 11

Slide 12

Slide 12 text

1.  概要 2.  基本的な使い⽅ •  準備 •  UI部品の検索と操作 •  待ち合わせ 3.  Tips 4.  UI Automator2の使いどころ 5.  まとめ 12

Slide 13

Slide 13 text

UI部品の検索と操作: 基本形 13 VJ%FWJDFGJOE0CKFDU ᫰✝ᦴঽ ៫ਃ •  ᫰✝ᦴঽに合致したUI部品を៫ਃする •  GJOE0CKFDU メソッドが2つ •  6J0CKFDUGJOE0CKFDU 6J4FMFDUPS •  6J0CKFDUGJOE0CKFDU #Z4FMFDUPS 引数・戻り値の型に注⽬!

Slide 14

Slide 14 text

UI部品の検索と操作: 検索(1/2) 14 •  GJOE0CKFDU メソッドが2つ •  6J0CKFDUGJOE0CKFDU 6J4FMFDUPS •  6J0CKFDUGJOE0CKFDU #Z4FMFDUPS •  6J4FMFDUPS検索条件の例(旧uiautomator互換) •  #Z4FMFDUPS検索条件の例(UI Automator2 新API) OFX6J4FMFDUPS UFYU 0, DMBTT/BNF #VUUPODMBTT #ZUFYU 0, DMB[[ #VUUPODMBTT

Slide 15

Slide 15 text

UI部品の検索と操作: 検索(2/2) •  6J4FMFDUPS検索条件API •  #Z4FMFDUPS検索条件API 15 メソッド 概要 className(Class) Viewのクラス(EditTextやButtonなど)を条件に指定する text(String) Viewの表⽰⽂字列を条件に指定する description(String) ViewのcontentDescription属性値を条件に指定する resourceId(String) ViewのリソースID(⽂字列表現)を条件に指定する メソッド 概要 clazz(Class) Viewのクラス(EditTextやButtonなど)を条件に指定する text(String) Viewの表⽰⽂字列を条件に指定する desc(String) ViewのcontentDescription属性値を条件に指定する res(String) ViewのリソースID(⽂字列表現)を条件に指定する

Slide 16

Slide 16 text

UI部品の検索と操作: 操作 (6J0CKFDU/6J0CKFDUともに同じメソッド名) 16 メソッド 概要 click() クリックする setText(String) 指定された⽂字列を⼊⼒する getText() 設定されている⽂字列を取得する isFocused() フォーカスが当たっているかどうかを取得する

Slide 17

Slide 17 text

UI部品の検索と操作: 使⽤例 「"OK"ボタン」をクリックする例 17 6J4FMFDUPS6J0CKFDUӼਜҰ࿾൶ 6J0CKFDUPL#VUUPOVJ%FWJDFGJOE0CKFDU OFX6J4FMFDUPS UFYU 0, DMBTT/BNF #VUUPODMBTT PL#VUUPODMJDL #Z4FMFDUPS6J0CKFDUӼਜҰ࿾൶ 6J0CKFDUPL#VUUPOVJ%FWJDFGJOE0CKFDU #Z UFYU 0, DMB[[ #VUUPODMBTT PL#VUUPODMJDL

Slide 18

Slide 18 text

UI部品の検索と操作: 検索タイミング 6J4FMFDUPS6J0CKFDUを使う場合 •  6J0CKFDUの操作メソッドを呼び出したとき ※GJOE0CKFDU 6J4FMFDUPS 呼び出し時ではない •  ⾒付からなかったら6J0CKFDU/PU'PVOE&YDFQUJPO •  画⾯レイアウトが変わっても同⼀6J0CKFDU使いまわせる #Z4FMFDUPS6J0CKFDUを使う場合 •  GJOE0CKFDU #Z4FMFDUPS を呼び出したとき •  ⾒付からなかったらOVMMを返す •  画⾯レイアウトが変わると6J0CKFDUは無効になる →4UBMF0CKFDU&YDFQUJPO 18

Slide 19

Slide 19 text

UI部品の検索と操作: 検索範囲指定 あるUIサブツリーの下だけ 検索する • UiSelector/UiObjectを使う場合: • BySelector/UiObject2を使う場合: 19 6J4FMFDUPSDSJUFSJB ᫰✝ӘゼᾂDIJME4FMFDUPS ᫰✝ᦴঽ 6J0CKFDUUBSHFUVJ%FWJDFGJOE0CKFDU DSJUFSJB 6J0CKFDUSPPUVJ%FWJDFGJOE0CKFDU ᫰✝Әゼᾂ 6J0CKFDUUBSHFUSPPUGJOE0CKFDU ᫰✝ᦴঽ ᫰✝Әゼᾂ

Slide 20

Slide 20 text

UI部品の検索と操作: 検索範囲指定 あるUIサブツリーの下だけ 検索する • UiSelector/UiObjectを使う場合: • BySelector/UiObject2を使う場合: 20 6J4FMFDUPSDSJUFSJBOFX6J4FMFDUPS SFTPVSDF*E.BUDIFT JEMBZPVU DIJME4FMFDUPS OFX6J4FMFDUPS UFYU 0, VJ%FWJDFGJOE0CKFDU DSJUFSJB DMJDL 6J0CKFDUSPPUVJ%FWJDFGJOE0CKFDU #Z SFT 1BUUFSODPNQJMF JEMBZPVU SPPUGJOE0CKFDU #ZUFYU 0, DMJDL 「layout2」の下にある 「OK」ボタンを押す

Slide 21

Slide 21 text

UI部品の検索と操作: 検索範囲指定 注意点: 「探索深さ」を指定したいとき 21 6J0CKFDUSPPUVJ%FWJDFGJOE0CKFDU #Z SFT 1BUUFSODPNQJMF JEMBZPVU SPPUGJOE0CKFDU #ZUFYU 0, EFQUI DMJDL 「layout1」の直接の⼦供 (探索深さ1限定) の「OK」ボタンを押したい •  UiSelector/UiObjectを使う場合: 不可 •  BySelector/UiObject2を使う場合: EFQUI を使う

Slide 22

Slide 22 text

UI部品の検索と操作: スクロール スクロールすれば現れる画⾯外の部品操作 22 [Developer options] →[Show touches] をタップしたい 6J4DSPMMBCMFMJTU OFX6J4DSPMMBCMF OFX6J4FMFDUPS DMBTT/BNF -JTU7JFXDMBTT EFW0QUJPOT-JTUTFU"T7FSUJDBM-JTU 6J0CKFDUTIPX5PVDIFTMJTUHFU$IJME#Z5FYU OFX6J4FMFDUPS DMBTT/BNF -JOFBS-BZPVUDMBTT 4IPXUPVDIFT TIPX5PVDIFTDMJDL GJOE0CKFDU 使わない 「"Show touches"を⼦孫に持ったLinearLayout」を探す

Slide 23

Slide 23 text

UI部品の検索と操作: スクロール スクロールすれば現れる画⾯外の部品操作 • 旧uiautomator時代のAPIしか無い •  6J4DSPMMBCMFは6J0CKFDUのサブクラス •  いきなりOFXするスタイル • 気持ち悪いが割り切って使い続けるしかない 23

Slide 24

Slide 24 text

UI部品の検索と操作: まとめ • ⽬的の似たAPIが2セット存在 •  UiSelector/UiObject (旧uiautomator互換) •  BySelector/UiObject2 (新規追加) • 両者で検索タイミングが微妙に異なる •  操作時 vs findObject()時 • 新しいBySelector/UiObject2は細かい部分で改善 •  直接の⼦供の検索 • スクロールサポートは旧APIのみ 24

Slide 25

Slide 25 text

1.  概要 2.  基本的な使い⽅ •  準備 •  UI部品の検索と操作 •  待ち合わせ 3.  Tips 4.  UI Automator2の使いどころ 5.  まとめ 25

Slide 26

Slide 26 text

待ち合わせ: 概要 • 原則: 操作による画⾯更新を待たずに次に進む •  独⽴した複数のボタン・テキストボックスを 連続操作するときは速くて便利 • 以下のようなケースでは同期(待ち合わせ)が必要 •  直前の操作による画⾯の変化に依存した操作 •  ボタンを押すとTextViewの表⽰が変わることを確認したい •  テキストボックスに⽂字を⼊⼒し、enabledになった ボタンを押したい •  etc. •  ある操作で画⾯遷移・ダイアログ表⽰が発⽣するとき •  画⾯遷移・ダイアログ表⽰を完了してから次の操作をしたい 26

Slide 27

Slide 27 text

待ち合わせ: UiSelector/UiObject 6J0CKFDUの「操作+待ち合わせ」メソッドを呼ぶ 27 メソッド(引数はタイムアウト値) 概要 clickAndWaitForNewWindow(long) クリックしてから、新しい窓 (ダイアログなど)が表⽰されるまで待つ waitForExists(long) このViewが表⽰されるまで待つ waitUntilGone(long) このViewが消えるまで待つ ※タイムアウトした場合は、falseが返される ѷ0,ѸՄԧ՛ӼᚭӁӐѬԨԌԊՕԘҶⷭ⒈ҿӶӵӨӑᑻӎ 6J0CKFDUPL#VUUPOVJ%FWJDFGJOE0CKFDU OFX6J4FMFDUPS UFYU 0, DMBTT/BNF #VUUPODMBTT ԨԌԊՕԘҶⷭ⒈ҿӶӵӨӑNTFDᑻӎѭԧԌՈԊԎ԰ᣪәԮԡ԰Ⴃᡇѭ BTTFSU5IBU PL#VUUPODMJDL"OE8BJU'PS/FX8JOEPX - JT USVF ҽҽҵӳⷭ⒈ҿӶӉԨԌԊՕԘӕሽӃӵ៫ਃӼ⷗Ұ

Slide 28

Slide 28 text

待ち合わせ: BySelector/UiObject2 6J0CKFDUの汎⽤的なメソッドを呼ぶ 28 メソッド(引数は条件とタイムアウト値) 概要 clickAndWait(EventCondition, long) クリックしてから、指定された条件が満 たされるまで待つ wait(SearchCondition, long) 指定された条件が満たされるまで待つ wait(UiObject2Condition, long) 指定された条件が満たされるまで待つ ※タイムアウトした場合は、null/0/falseが返される 良く使う「条件」は6OUJMクラスに⽤意されている Untilクラスのstaticメソッド 概要 newWindow() 新しい窓(ダイアログ)が表⽰されるまで gone(BySelector) 条件に合致するViewが⾒付からなくなるまで textEquals(String) 表⽰⽂字列が引数で指定された通りになるまで

Slide 29

Slide 29 text

待ち合わせ: BySelector/UiObject2 29 ѷ0,ѸՄԧ՛ӼᚭӁӐѬԨԌԊՕԘҶⷭ⒈ҿӶӵӨӑᑻӎ 6J0CKFDUPL#VUUPO VJ%FWJDFGJOE0CKFDU #ZUFYU 0, DMB[[ #VUUPODMBTT ԨԌԊՕԘҶⷭ⒈ҿӶӵӨӑNTFDᑻӎ CPPMFBOSFTVMUPL#VUUPODMJDL"OE8BJU 6OUJMOFX8JOEPX - ԧԌՈԊԎ԰ӁӉӒҷәԮԡ԰ӼႣᡇҿӅӵ BTTFSU5IBU SFTVMU JT USVF ҽҽҵӳԨԌԊՕԘӘ៫ਃӔӓӼ⷗Ұ

Slide 30

Slide 30 text

待ち合わせ: いつでも使えるもの UiDeviceクラスのメソッドを呼ぶ 30 メソッド(引数はタイムアウト値) 概要 wait(SearchCondition, long) 指定された条件が満たされるまで待つ waitForWindowUpdate(String, long) 同⼀画⾯内のUIが更新されるまで待つ ※第1引数はアプリのパッケージ名 performActionAndWait(Runnab le, EventCondition, long) 指定されたアクション(Runnable)を実⾏し、 条件が満たされるまで待つ waitForIdle(long) このアプリがアイドル状態になるまで待つ

Slide 31

Slide 31 text

待ち合わせ: 注意 •  OFX8JOEPX系とXJOEPX6QEBUF系の違い ※間違うとタイムアウトするので注意 •  新しい窓(ダイアログ含む)が表⽰されるとき: OFX8JOEPX系 •  同じ窓の中が変化するとき: XJOEPX6QEBUF系 •  待ち合わせメソッドの戻り値は必ずBTTFSUする •  タイムアウトしても例外は発⽣しない •  「戻る」キー押下後の待ち合わせには 6J%FWJDFXBJU 4FBSDI$POEJUJPO MPOH を使う (例)XBJU 6OUJMIBT0CKFDU #ZQLH UJNFPVU •  既存"DUJWJUZのSFTVNFは「新しい窓」ではない 31

Slide 32

Slide 32 text

待ち合わせ: まとめ •  画⾯の変化を待ってから操作する場合は待ち合わせが必要 •  UiSelector/UiObject: 待ち合わせに使える条件が少ない •  ある程度UiDeviceのメソッドでカバー可能 •  BySelector/UiObject2: 待ち合わせ条件を柔軟に指定可能 •  Untilクラスに良く使う待ち合わせ条件がまとまっている •  こまかい注意事項あり •  OFX8JOEPX vs XJOEPX6QEBUF •  待ち合わせの成功確認は⼤事! •  戻るボタン後の画⾯遷移 32

Slide 33

Slide 33 text

1.  概要 2.  基本的な使い⽅ •  準備 •  UI部品の検索と操作 •  待ち合わせ 3.  Tips 4.  UI Automator2の使いどころ 5.  まとめ 33

Slide 34

Slide 34 text

UIの監視: UiWatcher •  6J8BUDIFS: ⽬的のUI部品が⾒つからなかったときに発動するリスナ •  リスナ発動後にUI部品の検索・操作をリトライする。 •  ユースケース: テストを失敗しにくくするのに有効! •  ⾊々な画⾯で表⽰されるダイアログを操作する (セッション切れ時のログイン画⾯、レビューお願い画⾯、etc) •  ANR/強制終了ダイアログを閉じてテストを続⾏する •  etc. •  詳細は以下のURLで! ※古い記事ですが考え⽅は同じです •  http://sumio.hatenablog.com/entry/2014/04/06/014941 34

Slide 35

Slide 35 text

UIの監視: 注意点 • リスナ発動タイミング •  6J0CKFDUの操作メソッド呼び出し時 UI部品が⾒つかるか、タイムアウトするまで、 1秒おきに何回も呼び出される •  GJOE0CKFDU #Z4FMFDUPS 呼び出し時 UI部品が⾒つからなかったら Window1つにつき1回だけ呼び出される • Espressoとは連携しない •  EspressoのAPI(PO7JFX で⾒付からなかったとき) では発動しない ※混ぜて使うときは注意! 35

Slide 36

Slide 36 text

タイムアウト値: 定義 • $POGJHVSBUPSクラスに4種類存在 Idle Timeout: アクセシビリティイベントキューのアイドル待ち時間 Selector Timeout: UI部品が⾒えるまでの待ち時間 Action Acknowledgment Timeout: UI部品操作が完了するまでの待ち時間 Scroll Acknowledgment Timeout: スクロール操作が完了するまでの待ち時間 36

Slide 37

Slide 37 text

タイムアウト値: 待つタイミング •  Idle Timeout •  Home/Backキーなど押下直前 (この時間内にアイドル状態にならなければ諦めてキーを押す) •  6J0CKFDUを検索・操作する直前 (この時間内にアイドル状態にならなければ諦めて検索・操作する) •  Selector Timeout •  6J0CKFDUを検索するとき (この時間内に⾒付からなければ諦める) •  Action Acknowledgment Timeout •  6J0CKFDUを操作するとき (この時間内に操作が完了しなければ諦める) 37

Slide 38

Slide 38 text

タイムアウト値: 待つタイミング 利⽤するAPI(クラス)によって、 使われるタイムアウト値が異なる点に注意! 38 UiDevice UiObject UiObject2 Idle Timeout ○ × ○ Selector Timeout × ○ × Action Acknowledgment Timeout × ○ ×

Slide 39

Slide 39 text

WebViewの操作 •  検索・操作できるような"1*は無い •  6J%FWJDFHFU-BTU5SBWFSTFE5FYU •  「最後に選択されたテキストを返す」 •  %1BEでフォーカス移動 Ȕ移動する度にこのメソッドを呼ぶと現在位置がわかる Ȕ⽬的のテキストに辿りついたら%1BEで操作する •  ⾊々やってみてもOVMMしか返してくれない •  8FC7JFXも操作したい場合はAppiumがおすすめ 詳しくは@ITの記事を参照 •  http://goo.gl/lsw8xf •  http://goo.gl/rUHIb8 39

Slide 40

Slide 40 text

1.  概要 2.  基本的な使い⽅ •  準備 •  UI部品の検索と操作 •  待ち合わせ 3.  Tips 4.  UI Automator2の使いどころ 5.  まとめ 40

Slide 41

Slide 41 text

使いどころ: Espressoとの併⽤ • 1つのテストメソッド内で Espresso・UI Automator両⽅のAPIを併⽤可能 •  基本Espressoでテストを書く •  Espressoでテストできない箇所だけUI Automatorを使う • 併⽤は簡単 •  UiDeviceをsetUp()時に初期化しておけばOK •  ⾃由に混ぜて利⽤可 41

Slide 42

Slide 42 text

使いどころ: ユースケース • 事前条件のセットアップ •  ロケールを切り替えてからテストを開始する •  WiFiをOFFにしてからテストを開始する •  etc. • システムダイアログの操作 •  MarshmallowのRuntime Permissionダイアログ操作 •  ANR/強制終了ダイアログの操作 • 連携先アプリの操作 42

Slide 43

Slide 43 text

使いどころ: Espresso併⽤時の注意点 世界を切り替えるときには待ち合わせを忘れずに &TQSFTTPȒȔ6*"VUPNBUPS 43 㘘⼱ᎅӕԊԗԣԡӃӵӉӫӘՄԧ՛ӼᚭӃ PO7JFX XJUI*E 3JECVUUPO@DPOUBDUT QFSGPSN DMJDL ԹդՇԫԟՏ՛␼⽇ԨԌԊՕԘӼ៫ਃ VJ%FWJDFXBJU 6OUJMGJOE0CKFDU #ZSFT DPNBOESPJEQBDLBHFJOTUBMMFS QFSNJTTJPO@BMMPX@CVUUPO 5*.&065@7"-6& DMJDL ஝Ꮜ㘘⼱ᎅԊԗԣԡՄԧ՛ӼᚭӃ VJ%FWJDFXBJU 6OUJMIBT0CKFDU #ZSFT 1BUUFSODPNQJMF JECVUUPO@DPOUBDUT 5*.&065@7"-6& PO7JFX XJUI*E 3JECVUUPO@DPOUBDUT QFSGPSN DMJDL UI Automatorで操作したいボタ ンが表⽰されるまで待つ Espressoで操作したい ボタンが表⽰されるまで待つ

Slide 44

Slide 44 text

1.  概要 2.  基本的な使い⽅ •  準備 •  UI部品の検索と操作 •  待ち合わせ 3.  Tips 4.  UI Automator2の使いどころ 5.  まとめ 44

Slide 45

Slide 45 text

まとめ •  UI Automator2について解説しました •  Espressoでテストできない箇所だけUI Automator2の助け を借りると、スモールスタートできます •  6J0CKFDU vs 6J0CKFDUの微妙な違いに注意! •  スクロールが必要なところ以外は6J0CKFDUを使っておけば安⼼ •  細かい点で困ったらこの資料を思い出してみてください 45 ご清聴ありがとうごうございました