DroidKaigi2017 - 変更に強いEspressoテストコードを効率良く書こう / DroidKaigi2017 - Let's Write Sustainable Espresso Test Rapidly

DroidKaigi2017 - 変更に強いEspressoテストコードを効率良く書こう / DroidKaigi2017 - Let's Write Sustainable Espresso Test Rapidly

DroidKaigi 2017で発表した
「変更に強いEspressoテストコードを効率良く書こう」(3/9 16:00-16:50 @ Room4)
のスライドです。

ライブコーディングが含まれますので、ビデオも合わせてご覧ください。
https://goo.gl/iKJcmg

実演に利用するサンプルアプリのソースコードは、以下より入手してください。
https://github.com/sumio/espresso-sample-for-droidkaigi2017

また、発表中に紹介したユーティリティメソッドだけを切りだしたものは、こちらから入手できます。
https://github.com/sumio/espresso-commons

17997dee8a3da090f62d8cf8c494d8ff?s=128

TOYAMA Sumio

March 09, 2017
Tweet

Transcript

  1. 変更に強いEspressoテストコード を効率良く書こう 2017.03.09 外⼭ 純⽣ (sumio_tym) 1 DroidKaigi 2017

  2. ⾃⼰紹介 p ⽒名: 外⼭ 純⽣ (TOYAMA Sumio) @sumio_tym (Twitter) /

    @sumio (GitHub) p 所属: NTTソフトウェア株式会社 p 業務内容: p 社内Androidプロジェクトの技術⽀援 p 社内Androidプロジェクトのテスト⾃動化⽀援 p プライベート: p STAR(テスト⾃動化研究会) p @IT連載「スマホ向け無料システムテスト⾃動化 ツール」(UI Automator / Appiumの回を担当) 2
  3. お話しすること AndroidのUIテストツールEspresso について、以下を紹介します 3 プロダクトの仕様変更に強いテストを Espresso Test Recorderを使って 効率的に書いていく⽅法

  4. 話の流れ 1.イントロダクション p 効率的にテストを書くこと p 変更に強いテストを書くこと 2.Espressoの基本 3.Espresso Test Recorderとその限界

    4.実践!変更に強いテストを効率的に書く p サンプルアプリについて p テスト⾃動化対象の選定 p 操作・検証の記録 p 修正 4
  5. 1.イントロダクション p 効率的にテストを書くこと p 変更に強いテストを書くこと 2.Espressoの基本 3.Espresso Test Recorderとその限界 4.実践!変更に強いテストを効率的に書く

    p サンプルアプリについて p テスト⾃動化対象の選定 p 操作・検証の記録 p 修正 5
  6. 効率的にテストを書くことの⼤切さ テスト⾃動化の⽬的は⾊々ある pテスト実施⼯数を削減したい p⼿順ミス、確認ミスをなくしたい p回帰試験を⾃動化して安⼼したい petc. 6

  7. 効率的にテストを書くことの⼤切さ pどんなケースでも テストを書くのに時間を浪費する と⽬的達成が難しくなる p特に、着⼿するときは、 効率的に(楽して)テストを書く ことはとても⼤切 7

  8. UIテスト実装時のボトルネック(イメージ) 操作対象の特定が⼤変 (例)ダイアログのメッセージ⽂字列を検証する p ダイアログタイトル: 「結果」 p ダイアログメッセージ: 「6 +

    7 = 13」 8
  9. 9 条件: ⼦孫に「結果」というtextを持つView の兄弟が⾃分の祖先におり、 かつ、⾃分はTextViewである。 UIテスト実装時のボトルネック(イメージ)

  10. 10 䗤䗣䗋䗞䗚䗬 䗖䗡䗡䗄䗛 䗬䗞䗩䗝䖸䗡䗖䗨䗨䗃䗖䗢䗚 䗞䗨 5FYU7JFXDMBTTHFU/BNF 䗞䗨䖹䗚䗨䗘䗚䗣䗙䗖䗣䗩䗄䗛䖶 䗝䗖䗨䗈䗞䗗䗡䗞䗣䗜 䗝䗖䗨䖹䗚䗨䗘䗚䗣䗙䗖䗣䗩 䗬䗞䗩䗝䗉䗚䗭䗩

    ✿᧠ DIFDL 䗢䗖䗩䗘䗝䗚䗨 䗬䗞䗩䗝䗉䗚䗭䗩    ↓を⾃分でひねり出すのは正直厳しい... UIテスト実装時のボトルネック(イメージ)
  11. ボトルネック解消の切り札 Espresso Test Recorder pAndroid Studio 2.2より搭載 p以下をEspressoテストコードとして出⼒ pUIの操作 p結果の検証(assertion)

    とはいえ、うまく動かないケースも... 11
  12. 効率的にテストを書くためには? できるだけ Espresso Test Recorderが得意な テストケースを⾃動化対象にする pもちろん ⾃動化の⽬的から外れていないか の検討は必要です。 12

  13. 効率的にテストを書くためには? そのため知っておくと良いことは? pEspresso Test Recorderが 得意なケース/不得意なケース pEspressoのコードを⼿で書けば 簡単なケース/困難・不可能なケース 後程紹介します! 13

  14. 1.イントロダクション p 効率的にテストを書くこと p 変更に強いテストを書くこと 2.Espressoの基本 3.Espresso Test Recorderとその限界 4.実践!変更に強いテストを効率的に書く

    p サンプルアプリについて p テスト⾃動化対象の選定 p 操作・検証の記録 p 修正 14
  15. 変更に強いテストとは? 画⾯の仕様変更が発⽣したときに テストコード修正インパクトが⼩さい こと 15

  16. 変更に弱いテストの典型例 p操作対象を特定するコードが、 多くのテストケースにコピー されている場合 16

  17. 変更に弱いテストの典型例(イメージ) 17 ログイン画⾯のテストケースを考える 1. ID/PWを⼊れて「ログイン」と表⽰されたボタン を押すと〜されること 2. PWが未⼊⼒で「ログイン」と表⽰されたボタン を押すと〜されること 3.

    IDが未⼊⼒で「ログイン」と表⽰されたボタン を押すと〜されること 後で「ログイン」ボタンが「OK」ボタンに 仕様変更されると、全部修正が必要!
  18. 変更に弱いテストの典型例(イメージ) 18 ログイン画⾯のテストケースを考える 1. ID/PWを⼊れて「ログイン」と表⽰されたボタン を押すと〜されること 2. PWが未⼊⼒で「ログイン」と表⽰されたボタン を押すと〜されること 3.

    IDが未⼊⼒で「ログイン」と表⽰されたボタン を押すと〜されること Espresso Test Recorderで普通に記録すると、 こうなってしまう!
  19. 変更に強くするには?(イメージ) 同じ操作を共通部分として抽出する 1. ID/PWを⼊れてログインすると〜されること 2. PWが未⼊⼒でログインすると〜されること 3. IDが未⼊⼒でログインすると〜されること ※ここで、「ログインする」= 「『ログイン』と表⽰されたボタンを押す」

    後で「ログイン」ボタンが「OK」ボタンに 仕様変更されても「※」だけ修正すればOK cf. PageObject デザインパターン 19
  20. 変更に強くするには?(イメージ) 同じ操作を共通部分として抽出する 1. ID/PWを⼊れてログインすると〜されること 2. PWが未⼊⼒でログインすると〜されること 3. IDが未⼊⼒でログインすると〜されること ※ここで、「ログインする」= 「『ログイン』と表⽰されたボタンを押す」

    Espresso Test Recorderで記録した場合、 共通部分の抽出は⼿作業で⾏う必要がある! 20
  21. 変更に強いコードに直す⽅法は? 以下を修得しておくと負担が減る pEspresso Test Recroderの出⼒に対して 具体的な修正⽅針をイメージする p修正作業で良く使うAndroid Studioの リファクタ機能を覚える (キーボードショートカットも覚える)

    後程紹介します! 21
  22. ここまでのまとめ 効率的にテストを書くためには pEspresso Test Recorderの得意箇所から着⼿ p 得⼿不得⼿を知っておく必要がある 変更に強いテストにするには pEspresso Test

    Recorderの出⼒コードから、 ⼿作業で共通部分を抽出 p リファクタ機能を駆使した具体的な修正⽅法を 修得しておく必要がある 22
  23. 1.イントロダクション p 効率的にテストを書くこと p 変更に強いテストを書くこと 2.Espressoの基本 3.Espresso Test Recorderとその限界 4.実践!変更に強いテストを効率的に書く

    p サンプルアプリについて p テスト⾃動化対象の選定 p 操作・検証の記録 p 修正 23
  24. Espressoの概要 p Android公式のUIテストフレームワーク p コードの簡潔さ・信頼性の⾼さに定評あり p テスト実⾏速度が⽐較的速い p WebViewにも対応 p

    URL phttps://goo.gl/x8eP5C phttps://goo.gl/lmrlJI 24 (※) https://google.github.io/android-testing-support-library/docs/espresso/cheatsheet/ よりロゴを引⽤ (※)
  25. Espressoのセットアップ ビルド環境設定(https://goo.gl/WlXSCq) p Android Support Repositoryのインストール p build.gradleのdependenciesブロック (以下の2つのモジュールを宣⾔) p

    configuration: androidTestCompile p group: com.android.support.test.espresso p module: 1. espresso-core (Recorderが⾃動設定する) 2. espresso-contrib (⼿動で追加する) 25
  26. Espressoのセットアップ 26 androidTestCompile( 'com.android.support.test.espresso:espresso-core:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations'

    } ) プロダクトコードとコンフリクト するモジュールを除外する。 (ビルドエラー時のメッセージを参照)
  27. Espressoのセットアップ 27 androidTestCompile( 'com.android.support.test.espresso:espresso-contrib:2.2.2', { exclude group: 'com.android.support', module: 'support-annotations'

    exclude group: 'com.android.support', module: 'support-v4' exclude group: 'com.android.support', module: 'appcompat-v7' exclude group: 'com.android.support', module: 'design' exclude group: 'com.android.support', module: 'recyclerview-v7' } )
  28. Espressoのセットアップ テスト⾛⾏端末のアニメーション設定 (「開発者オプション」の以下をOFFにする) p ウィンドウアニメスケール p トランジションアニメスケール p アニメーター再⽣時間スケール 28

  29. Espressoのテストコード p src/androidTest/java に配置 p Android Testing Support Libraryに従う ※

    Espresso Test Recorderが雛型を⾃動⽣成 29 @RunWith(AndroidJUnit4.class) public class MyEspressoTest { @Rule public ActivityTestRule<...> activityTestRule = ...; ... }
  30. Espresso APIの概要 p 以下の基本形を理解する ※perform()・check()は省略可能 30 onView(ViewMatcher) .perform(ViewAction) .check(ViewAssertion); n「ViewMatcher」にあてはまるViewに対して

    n「ViewAction」を実⾏した結果 nそのViewが「ViewAssertion」 を満たすことを確認する
  31. Espresso APIの概要 31 onView(ViewMatcher) .perform(ViewAction) .check(ViewAssertion); ⽤意されているAPIの⼀覧は チートシート(https://goo.gl/sH9eax)参照 n「ViewMatcher」にあてはまるViewに対して n「ViewAction」を実⾏した結果

    nそのViewが「ViewAssertion」 を満たすことを確認する
  32. Espressoで操作・確認できること p Button、EditText、TextView、ダイアログな どの基本的なコンポーネント p ListView - onData() p RecyclerView

    – RecyclerViewActions ※ViewHolder内のViewの確認には⼯夫が必要 p NavigationDrawer・NavigationView - DrawerActions・NavigationViewActions p DatePicker・TimePicker - PickerActions p WebView内HTML - onWebView() https://goo.gl/OMfVyZ 参照 32
  33. Espressoで不得意・困難なこと Viewのプロパティの動的な取得 (事前に分かっている値との⼀致確認はできる) p View AとView Bに同じテキスト (事前に分からない) が表⽰されていることを確認する、など 操作・確認対象が明確でないケース

    p 複雑なジェスチャー(画⾯を指でなぞる など) p 画像の⽐較(ImageViewなど) 33
  34. Espressoで不得意・困難なこと AsyncTask以外の⾮同期待ち合わせ p IdlingResourceを実装すれば可能 p 別Activityに遷移すると 「UIが変化するまで待つ」のが難しい 34

  35. ここまでのまとめ 環境設定は、 Espresso Test Recorderに任せるのが楽 p 端末のアニメーションOFFなど⼿動設定も必要 ⼤部分のUI部品の操作・確認をサポート p 公式にチートシートあり

    以下については近付かないのが無難 p Viewプロパティの動的な取得 p 操作・確認対象が明確でないケース p 別画⾯遷移後の⾮同期待ち合わせ 35
  36. 1.イントロダクション p 効率的にテストを書くこと p 変更に強いテストを書くこと 2.Espressoの基本 3.Espresso Test Recorderとその限界 4.実践!変更に強いテストを効率的に書く

    p サンプルアプリについて p テスト⾃動化対象の選定 p 操作・検証の記録 p 修正 36
  37. 動作に必要なもの pテスト対象アプリのソースコード pAndroid Studio 2.2以上 pエミュレータ/実機 (テスト記録時に使⽤) 37

  38. 動かしかた 1. エミュレータ/実機をadb接続しておく 2. テスト対象アプリのプロジェクトを Android Studioで開く 3. メニュー Run>

    Record Espresso Test 38
  39. 操作の記録 p 起動したテスト対象アプリを直接操作する p 操作した内容は「Record Your Test」ダイ アログに反映されていく (応答が遅いので、1アクションの都度、反 映されるまで待つのがお奨め)

    39 ※以降、 https://github.com/googlecodelabs/android-testing で公開されているサンプルアプリを使ったスクリーンショットを掲載しています。
  40. アサーションの記録 p 「Record Your Test」 >「Add Assertion」 40

  41. アサーションの記録 41 p 画⾯キャプチャが表⽰され、 アサーションを記録するモードに移⾏

  42. アサーションの記録 42 p 画⾯キャプチャ上で、検証したい箇所を選択 p 検証内容を選択し「Save Assertion」

  43. 記録の終了 43 p 「Record Your Test」 >「OK」 p テストクラス名を⼊⼒ ※

    build.gradleが未設定だと、 このタイミングで⾃動設定 するかどうか確認される。
  44. 限界 - 注意点 p 操作がもっさり (できれば実機で記録するのが良い) p ⾮対応のコンポーネントがある p 確認⼿段が限定されている

    「テキスト⼀致・表⽰されているかどうか」のみ p 操作誤りをアンドゥできない p 必ず最初のActivity起動から記録される p ランドスケープ⾮対応(Assertion) 44
  45. 限界 - コンポーネント別対応状況 45 コンポーネント 対応状況 TextView ◦ EditText ◦

    Button ◦ NavigationDrawer ◦ (専⽤APIは使われない) RecyclerView △ (専⽤APIは使われない) ListView △ (onData()が使われない) Picker系 △ (spinner系のみ可) WebView内HTML ×
  46. 限界 - バグと思われるもの p ⾃動⽣成されるchildAtPosition()が、 正しく位置をカウントしない (Issue 231461) MoreViewMatchersクラス(⾃作)修正版あり p

    AsyncTask以外のバックグラウンドスレッド (OkHttpやRxJavaなど)を使っていると、 巨⼤なsleepコードが挿⼊されることがある 例: Thread.sleep(3596585)←約1時間! 46
  47. ここまでのまとめ p Espresso Test Recorderの操作は 直感的で分かりやすい p ただし、何でも記録できるわけでは無い ので、事前に限界を知っておくと良い pRecyclerView、ListView、Picker系、

    WebViewがある画⾯は注意が必要 (必要に応じてソースを書き換える) 47
  48. 1.イントロダクション p 効率的にテストを書くこと p 変更に強いテストを書くこと 2.Espressoの基本 3.Espresso Test Recorderとその限界 4.実践!変更に強いテストを効率的に書く

    p サンプルアプリについて p テスト⾃動化対象の選定 p 操作・検証の記録 p 修正 48
  49. サンプルアプリ 49 (Chrome Custom Tabs) タイトル2 タイトル1 ・・・・ タイトル3 タイトル2

    Qiita記事⼀覧 お気に⼊り⼀覧 ★(CheckBox)タップで お気に⼊り⼀覧に⼊る タイトルタップで 詳細画⾯へ 記事詳細 NavigationDrawerで切り替え
  50. 1.イントロダクション p 効率的にテストを書くこと p 変更に強いテストを書くこと 2.Espressoの基本 3.Espresso Test Recorderとその限界 4.実践!変更に強いテストを効率的に書く

    p サンプルアプリについて p テスト⾃動化対象の選定 p 操作・検証の記録 p 修正 50
  51. 効率的にテストを書くためには? pできるだけ Espresso Test Recorderが得意な テストケースを⾃動化対象にする pもちろん ⾃動化の⽬的から外れていないか の検討は必要です。 51

    再掲
  52. テスト⾃動化対象の選択⽅針 以下の条件に合う画⾯のテストを 優先的に⾃動化する (Espressoは画⾯単位で試験する) pEspresso Test Recorderが対応してい るコンポーネントが多い p(対応していないコンポーネントは) ⼿書きでEspresso

    APIを呼び出せば 簡単に書ける 52
  53. コンポーネント別対応状況まとめ 53 コンポーネント Recorder ⼿書き TextView ◦ ◦ EditText ◦

    ◦ Button ◦ ◦ NavigationDrawer ◦ ◦ RecyclerView △ △ ListView △ ◦ Picker系 △ ◦ WebView内HTML × ◦ より多く より 少なく
  54. その他対応状況まとめ 54 やりたいこと Recorder ⼿書き 表⽰テキスト⼀致確認 ◦ ◦ Viewの表⽰⾮表⽰確認 ◦

    ◦ その他の確認 × △ (画像⼀致確認) × × Viewプロパティ の動的な取得 × × 複雑なジェスチャー × × AsyncTask以外の⾮同 期待ち合わせ × △ より多く より 少なく 対象外
  55. サンプルアプリで考える 55 (Chrome Custom Tabs) タイトル2 タイトル1 ・・・・ タイトル3 タイトル2

    Qiita記事⼀覧 お気に⼊り⼀覧 ★(CheckBox)タップで お気に⼊り⼀覧に⼊る タイトルタップで 詳細画⾯へ 記事詳細 NavigationDrawerで切り替え 別プロセス
  56. 56 タイトル2 タイトル1 ・・・・ タイトル3 タイトル2 Qiita記事⼀覧 お気に⼊り⼀覧 ★(CheckBox)タップで お気に⼊り⼀覧に⼊る

    • 画像の変化は確認不可 Ø CheckBoxなので 「チェック状態かどうか(isChecked())」 で判定する。 サンプルアプリで考える(★のタップ操作)
  57. 57 タイトル2 タイトル1 ・・・・ タイトル3 タイトル2 Qiita記事⼀覧 お気に⼊り⼀覧 ★(CheckBox)タップで お気に⼊り⼀覧に⼊る

    • RecyclerViewのビューアイテム内の操作・ 確認が難しい Ø 汎⽤メソッドを⽤意して対応する (後述) サンプルアプリで考える(★のタップ操作)
  58. 58 タイトル2 タイトル1 ・・・・ タイトル3 タイトル2 Qiita記事⼀覧 お気に⼊り⼀覧 ★タップで お気に⼊り⼀覧に⼊る

    • お気に⼊りに⼊れたものと同じタイトル (事前に決まらない)が有ることの確認は不可 Ø サーバーレスポンスを固定する (事前に決まるようにする) Ø お気に⼊りの数が0→1になったこと への確認にとどめる(今回はこちらを採⽤) サンプルアプリで考える(お気に⼊り⼀覧)
  59. 今回⾃動化するテストケース 1. ☆をタップすると★に切り替わること 2. ★をタップすると☆に切り替わること 3. お気に⼊りが0件の状態で、☆をタップし て★にすると、お気に⼊り画⾯の表⽰件数 が1件になること (1件⽬が存在し、2件⽬が存在しないこと)

    59
  60. 1.イントロダクション p 効率的にテストを書くこと p 変更に強いテストを書くこと 2.Espressoの基本 3.Espresso Test Recorderとその限界 4.実践!変更に強いテストを効率的に書く

    p サンプルアプリについて p テスト⾃動化対象の選定 p 操作・検証の記録 p 修正 60
  61. 変更に弱いテストの典型例(イメージ) 61 ログイン画⾯のテストケースを考える 1. ID/PWを⼊れて「ログイン」と表⽰されたボタン を押すと〜されること 2. PWが未⼊⼒で「ログイン」と表⽰されたボタン を押すと〜されること 3.

    IDが未⼊⼒で「ログイン」と表⽰されたボタン を押すと〜されること Espresso Test Recorderで普通に記録すると、 こうなってしまう! 再掲
  62. 変更に強くするには?(イメージ) 同じ操作を共通部分として抽出する 1. ID/PWを⼊れてログインすると〜されること 2. PWが未⼊⼒でログインすると〜されること 3. IDが未⼊⼒でログインすると〜されること ※ここで、「ログインする」= 「『ログイン』と表⽰されたボタンを押す」

    後で「ログイン」ボタンが「OK」ボタンに 仕様変更されても「※」だけ修正すればOK cf. PageObject デザインパターン 62 再掲
  63. Recorderで記録するもの テスト時に操作・確認する可能性 のあるものを⼀度だけ記録する p ログインの例では・・・ p IDを⼊⼒する p PWを⼊⼒する p

    ログインボタンを押す p ログインエラーメッセージを確認する 63
  64. サンプルアプリに当てはめると p NavigationDrawerを開いて 投稿⼀覧画⾯に切り替える p 投稿⼀覧画⾯で☆をタップする p 投稿⼀覧画⾯で☆の存在を確認する p NavigationDrawerを開いて

    お気に⼊り⼀覧画⾯に切り替える p お気に⼊り⼀覧画⾯で リストアイテムの存在を確認する 64 デモ
  65. 1.イントロダクション p 効率的にテストを書くこと p 変更に強いテストを書くこと 2.Espressoの基本 3.Espresso Test Recorderとその限界 4.実践!変更に強いテストを効率的に書く

    p サンプルアプリについて p テスト⾃動化対象の選定 p 操作・検証の記録 p 修正 65
  66. 覚えておきたいIDEのテクニック 66 コマンド Mac Windows Extract Variable Cmd+Opt+V Ctrl+Alt+V Extract

    Method Cmd+Opt+M Ctrl+Alt+M Inline Cmd+Opt+N Ctrl+Alt+N Move Line UP Ctrl+Shift+↑ Alt+Shift+↑ Duplicate Line or Selection Cmd+D Ctrl+D Generate Cmd+N Alt+Insert Help>Find Action... で⼊⼒!
  67. 修正⽅針(Recorder出⼒結果を参考に) Recorder出⼒で、動かない箇所を修正する (RecyclerView関連) p CheckBoxのトグル p RecyclerViewActions.actionOnItemAtPosition() はアイテムビューそのものしか操作できない Ø 独⾃実装のclickDescendantViewWithId()

    を使ってアイテムビューの⼦孫を操作 (サンプルではRecyclerViewUtilsクラスで定義) 67 タイトル1 操作できる 操作できない デモ
  68. 修正⽅針(Recorder出⼒結果を参考に) Recorder出⼒で、動かない箇所を修正する (RecyclerView関連) p CheckBoxの状態確認 p 指定positionのアイテムビューを検索するAPI が無い Ø 独⾃実装の

    withItemViewAtPosition(recyclerView, pos) で実現 68 デモ
  69. 修正⽅針(Recorder出⼒結果を参考に) Recorder出⼒で、動かない箇所を修正する (RecyclerView関連) p CheckBoxの状態確認 Ø withItemViewAtPosition()とisDescendantOfA() を使って更に下の階層にあるCheckBoxを検索 allOf(isDescendantOfA(root), target)

    → root配下のtargetを検索する Ø 事前にRecyclerViewActions.scrollToPosition() でアイテムビューを画⾯に⼊れておく 69 デモ
  70. 修正⽅針(Recorder出⼒結果を参考に) Recorderのおかしな出⼒を修正する (RecyclerView関連) p リストアイテムの存在・不存在確認 p CheckBoxの状態確認と同様 p 事前にRecyclerViewActions.scrollToPosition() でスクロールしておくのを忘れない

    70 デモ
  71. 修正⽅針(Recorder出⼒結果を参考に) 以下のメソッドを切り出す(int引数は位置) 71 メソッド 概要 goArticleList() 投稿⼀覧ページへ goFavsList() Fav⼀覧ページへ toggleFavStatus(int)

    Favボタンのトグル assertFavStatus (int, boolean) Favボタン状態確認 assertItemExists(int) リストアイテム存在確認 assertItemDoesntExist (int) リストアイテム不存在確認 デモ
  72. テストケース実装 さきほど定義したメソッドのみを使って、 テストケースを実装する 1. ☆をタップすると★に切り替わること 2. ★をタップすると☆に切り替わること 3. お気に⼊りが0件の状態で、☆をタップし て★にすると、お気に⼊り画⾯の表⽰件数

    が1件になること (1件⽬が存在し、2件⽬が存在しないこと) 72 デモ
  73. 補⾜: RxJavaの待ち合わせについて 対応⽅法は諸説ある Schedulers.io()のみ利⽤の場合は③が良さそう ① RxAndroidのIssue #149 (結論は無いがサンプルコードあり) https://github.com/ReactiveX/RxAndroid/issues/149 ②

    RxEspresso (sub/unsubをカウントする) https://github.com/stablekernel/RxEspresso ③ Retrofitting Espresso (Schedulers.io()をAsyncTaskに差し替え) https://goo.gl/2p3E6S 73
  74. 補⾜: Espresso-Commons 今回紹介した⾃作ユーティリティだけ切 り出したものを 「Espresso-Commons」 として公開しています。 https://github.com/sumio/espresso-commons 74

  75. ここまでのまとめ 変更に強いテストコードを効率良く書く⽅ 法を実演を交じえて説明しました 1. 「Espressoで簡単に記録できる or 書ける」 という観点でテスト⾃動化対象を決める 2. テストに必要な操作・検証をRecorderで

    1回だけ記録する 3. 動かない出⼒を修正する 4. 操作・検証単位でメソッド抽出する 5. 抽出したメソッドのみを使ってテストを書く 75
  76. 最後に 変更に強いテストコードを効率良く書くに は、終盤で実演したアプローチに加えて、 知識や経験(引き出しを増やす)も重要です。 今回紹介したテクニックを⼟台に、まずは 1つ書いてみることをおすすめします。 ある程度軌道に乗ってから、 「難易度が⾼いが効果も⾼い箇所」 に挑戦するのがおすすめです。 76

  77. END ご清聴ありがとうございました! 77