Upgrade to Pro — share decks privately, control downloads, hide ads and more …

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

TOYAMA Sumio

March 09, 2017
Tweet

More Decks by TOYAMA Sumio

Other Decks in Technology

Transcript

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

    View Slide

  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

    View Slide

  3. お話しすること
    AndroidのUIテストツールEspresso
    について、以下を紹介します
    3
    プロダクトの仕様変更に強いテストを
    Espresso Test Recorderを使って
    効率的に書いていく⽅法

    View Slide

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

    View Slide

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

    View Slide

  6. 効率的にテストを書くことの⼤切さ
    テスト⾃動化の⽬的は⾊々ある
    pテスト実施⼯数を削減したい
    p⼿順ミス、確認ミスをなくしたい
    p回帰試験を⾃動化して安⼼したい
    petc.
    6

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  10. 10
    䗤䗣䗋䗞䗚䗬 䗖䗡䗡䗄䗛
    䗬䗞䗩䗝䖸䗡䗖䗨䗨䗃䗖䗢䗚
    䗞䗨 5FYU7JFXDMBTTHFU/BNF



    䗞䗨䖹䗚䗨䗘䗚䗣䗙䗖䗣䗩䗄䗛䖶 䗝䗖䗨䗈䗞䗗䗡䗞䗣䗜
    䗝䗖䗨䖹䗚䗨䗘䗚䗣䗙䗖䗣䗩
    䗬䗞䗩䗝䗉䗚䗭䗩 ✿᧠






    DIFDL 䗢䗖䗩䗘䗝䗚䗨
    䗬䗞䗩䗝䗉䗚䗭䗩



    ↓を⾃分でひねり出すのは正直厳しい...
    UIテスト実装時のボトルネック(イメージ)

    View Slide

  11. ボトルネック解消の切り札
    Espresso Test Recorder
    pAndroid Studio 2.2より搭載
    p以下をEspressoテストコードとして出⼒
    pUIの操作
    p結果の検証(assertion)
    とはいえ、うまく動かないケースも...
    11

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  15. 変更に強いテストとは?
    画⾯の仕様変更が発⽣したときに
    テストコード修正インパクトが⼩さい
    こと
    15

    View Slide

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

    View Slide

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

    View Slide

  18. 変更に弱いテストの典型例(イメージ)
    18
    ログイン画⾯のテストケースを考える
    1. ID/PWを⼊れて「ログイン」と表⽰されたボタン
    を押すと〜されること
    2. PWが未⼊⼒で「ログイン」と表⽰されたボタン
    を押すと〜されること
    3. IDが未⼊⼒で「ログイン」と表⽰されたボタン
    を押すと〜されること
    Espresso Test Recorderで普通に記録すると、
    こうなってしまう!

    View Slide

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

    View Slide

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

    View Slide

  21. 変更に強いコードに直す⽅法は?
    以下を修得しておくと負担が減る
    pEspresso Test Recroderの出⼒に対して
    具体的な修正⽅針をイメージする
    p修正作業で良く使うAndroid Studioの
    リファクタ機能を覚える
    (キーボードショートカットも覚える)
    後程紹介します!
    21

    View Slide

  22. ここまでのまとめ
    効率的にテストを書くためには
    pEspresso Test Recorderの得意箇所から着⼿
    p 得⼿不得⼿を知っておく必要がある
    変更に強いテストにするには
    pEspresso Test Recorderの出⼒コードから、
    ⼿作業で共通部分を抽出
    p リファクタ機能を駆使した具体的な修正⽅法を
    修得しておく必要がある
    22

    View Slide

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

    View Slide

  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/ よりロゴを引⽤
    (※)

    View Slide

  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

    View Slide

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

    View Slide

  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'
    }
    )

    View Slide

  28. Espressoのセットアップ
    テスト⾛⾏端末のアニメーション設定
    (「開発者オプション」の以下をOFFにする)
    p ウィンドウアニメスケール
    p トランジションアニメスケール
    p アニメーター再⽣時間スケール
    28

    View Slide

  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 = ...;
    ...
    }

    View Slide

  30. Espresso APIの概要
    p 以下の基本形を理解する
    ※perform()・check()は省略可能
    30
    onView(ViewMatcher)
    .perform(ViewAction)
    .check(ViewAssertion);
    n「ViewMatcher」にあてはまるViewに対して
    n「ViewAction」を実⾏した結果
    nそのViewが「ViewAssertion」
    を満たすことを確認する

    View Slide

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

    View Slide

  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

    View Slide

  33. Espressoで不得意・困難なこと
    Viewのプロパティの動的な取得
    (事前に分かっている値との⼀致確認はできる)
    p View AとView Bに同じテキスト
    (事前に分からない)
    が表⽰されていることを確認する、など
    操作・確認対象が明確でないケース
    p 複雑なジェスチャー(画⾯を指でなぞる など)
    p 画像の⽐較(ImageViewなど)
    33

    View Slide

  34. Espressoで不得意・困難なこと
    AsyncTask以外の⾮同期待ち合わせ
    p IdlingResourceを実装すれば可能
    p 別Activityに遷移すると
    「UIが変化するまで待つ」のが難しい
    34

    View Slide

  35. ここまでのまとめ
    環境設定は、
    Espresso Test Recorderに任せるのが楽
    p 端末のアニメーションOFFなど⼿動設定も必要
    ⼤部分のUI部品の操作・確認をサポート
    p 公式にチートシートあり
    以下については近付かないのが無難
    p Viewプロパティの動的な取得
    p 操作・確認対象が明確でないケース
    p 別画⾯遷移後の⾮同期待ち合わせ
    35

    View Slide

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

    View Slide

  37. 動作に必要なもの
    pテスト対象アプリのソースコード
    pAndroid Studio 2.2以上
    pエミュレータ/実機
    (テスト記録時に使⽤)
    37

    View Slide

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

    View Slide

  39. 操作の記録
    p 起動したテスト対象アプリを直接操作する
    p 操作した内容は「Record Your Test」ダイ
    アログに反映されていく
    (応答が遅いので、1アクションの都度、反
    映されるまで待つのがお奨め)
    39
    ※以降、 https://github.com/googlecodelabs/android-testing
    で公開されているサンプルアプリを使ったスクリーンショットを掲載しています。

    View Slide

  40. アサーションの記録
    p 「Record Your Test」
    >「Add Assertion」
    40

    View Slide

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

    View Slide

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

    View Slide

  43. 記録の終了
    43
    p 「Record Your Test」
    >「OK」
    p テストクラス名を⼊⼒
    ※ build.gradleが未設定だと、
    このタイミングで⾃動設定
    するかどうか確認される。

    View Slide

  44. 限界 - 注意点
    p 操作がもっさり
    (できれば実機で記録するのが良い)
    p ⾮対応のコンポーネントがある
    p 確認⼿段が限定されている
    「テキスト⼀致・表⽰されているかどうか」のみ
    p 操作誤りをアンドゥできない
    p 必ず最初のActivity起動から記録される
    p ランドスケープ⾮対応(Assertion)
    44

    View Slide

  45. 限界 - コンポーネント別対応状況
    45
    コンポーネント 対応状況
    TextView ○
    EditText ○
    Button ○
    NavigationDrawer ○ (専⽤APIは使われない)
    RecyclerView △ (専⽤APIは使われない)
    ListView △ (onData()が使われない)
    Picker系 △ (spinner系のみ可)
    WebView内HTML ×

    View Slide

  46. 限界 - バグと思われるもの
    p ⾃動⽣成されるchildAtPosition()が、
    正しく位置をカウントしない
    (Issue 231461)
    MoreViewMatchersクラス(⾃作)修正版あり
    p AsyncTask以外のバックグラウンドスレッド
    (OkHttpやRxJavaなど)を使っていると、
    巨⼤なsleepコードが挿⼊されることがある
    例: Thread.sleep(3596585)←約1時間!
    46

    View Slide

  47. ここまでのまとめ
    p Espresso Test Recorderの操作は
    直感的で分かりやすい
    p ただし、何でも記録できるわけでは無い
    ので、事前に限界を知っておくと良い
    pRecyclerView、ListView、Picker系、
    WebViewがある画⾯は注意が必要
    (必要に応じてソースを書き換える)
    47

    View Slide

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

    View Slide

  49. サンプルアプリ
    49
    (Chrome
    Custom Tabs)
    タイトル2 タイトル1
    ・・・・
    タイトル3
    タイトル2
    Qiita記事⼀覧
    お気に⼊り⼀覧
    ★(CheckBox)タップで
    お気に⼊り⼀覧に⼊る
    タイトルタップで
    詳細画⾯へ
    記事詳細
    NavigationDrawerで切り替え

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  53. コンポーネント別対応状況まとめ
    53
    コンポーネント Recorder ⼿書き
    TextView ○ ○
    EditText ○ ○
    Button ○ ○
    NavigationDrawer ○ ○
    RecyclerView △ △
    ListView △ ○
    Picker系 △ ○
    WebView内HTML × ○
    より多く
    より
    少なく

    View Slide

  54. その他対応状況まとめ
    54
    やりたいこと Recorder ⼿書き
    表⽰テキスト⼀致確認 ○ ○
    Viewの表⽰⾮表⽰確認 ○ ○
    その他の確認 × △
    (画像⼀致確認) × ×
    Viewプロパティ
    の動的な取得
    × ×
    複雑なジェスチャー × ×
    AsyncTask以外の⾮同
    期待ち合わせ
    × △
    より多く
    より
    少なく
    対象外

    View Slide

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

    View Slide

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

    View Slide

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

    View Slide

  58. 58
    タイトル2 タイトル1
    ・・・・
    タイトル3
    タイトル2
    Qiita記事⼀覧
    お気に⼊り⼀覧
    ★タップで
    お気に⼊り⼀覧に⼊る
    • お気に⼊りに⼊れたものと同じタイトル
    (事前に決まらない)が有ることの確認は不可
    Ø サーバーレスポンスを固定する
    (事前に決まるようにする)
    Ø お気に⼊りの数が0→1になったこと
    への確認にとどめる(今回はこちらを採⽤)
    サンプルアプリで考える(お気に⼊り⼀覧)

    View Slide

  59. 今回⾃動化するテストケース
    1. ☆をタップすると★に切り替わること
    2. ★をタップすると☆に切り替わること
    3. お気に⼊りが0件の状態で、☆をタップし
    て★にすると、お気に⼊り画⾯の表⽰件数
    が1件になること
    (1件⽬が存在し、2件⽬が存在しないこと)
    59

    View Slide

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

    View Slide

  61. 変更に弱いテストの典型例(イメージ)
    61
    ログイン画⾯のテストケースを考える
    1. ID/PWを⼊れて「ログイン」と表⽰されたボタン
    を押すと〜されること
    2. PWが未⼊⼒で「ログイン」と表⽰されたボタン
    を押すと〜されること
    3. IDが未⼊⼒で「ログイン」と表⽰されたボタン
    を押すと〜されること
    Espresso Test Recorderで普通に記録すると、
    こうなってしまう!
    再掲

    View Slide

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

    View Slide

  63. Recorderで記録するもの
    テスト時に操作・確認する可能性
    のあるものを⼀度だけ記録する
    p ログインの例では・・・
    p IDを⼊⼒する
    p PWを⼊⼒する
    p ログインボタンを押す
    p ログインエラーメッセージを確認する
    63

    View Slide

  64. サンプルアプリに当てはめると
    p NavigationDrawerを開いて
    投稿⼀覧画⾯に切り替える
    p 投稿⼀覧画⾯で☆をタップする
    p 投稿⼀覧画⾯で☆の存在を確認する
    p NavigationDrawerを開いて
    お気に⼊り⼀覧画⾯に切り替える
    p お気に⼊り⼀覧画⾯で
    リストアイテムの存在を確認する
    64
    デモ

    View Slide

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

    View Slide

  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... で⼊⼒!

    View Slide

  67. 修正⽅針(Recorder出⼒結果を参考に)
    Recorder出⼒で、動かない箇所を修正する
    (RecyclerView関連)
    p CheckBoxのトグル
    p RecyclerViewActions.actionOnItemAtPosition()
    はアイテムビューそのものしか操作できない
    Ø 独⾃実装のclickDescendantViewWithId()
    を使ってアイテムビューの⼦孫を操作
    (サンプルではRecyclerViewUtilsクラスで定義)
    67
    タイトル1
    操作できる 操作できない
    デモ

    View Slide

  68. 修正⽅針(Recorder出⼒結果を参考に)
    Recorder出⼒で、動かない箇所を修正する
    (RecyclerView関連)
    p CheckBoxの状態確認
    p 指定positionのアイテムビューを検索するAPI
    が無い
    Ø 独⾃実装の
    withItemViewAtPosition(recyclerView, pos)
    で実現
    68
    デモ

    View Slide

  69. 修正⽅針(Recorder出⼒結果を参考に)
    Recorder出⼒で、動かない箇所を修正する
    (RecyclerView関連)
    p CheckBoxの状態確認
    Ø withItemViewAtPosition()とisDescendantOfA()
    を使って更に下の階層にあるCheckBoxを検索
    allOf(isDescendantOfA(root), target)
    → root配下のtargetを検索する
    Ø 事前にRecyclerViewActions.scrollToPosition()
    でアイテムビューを画⾯に⼊れておく
    69
    デモ

    View Slide

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

    View Slide

  71. 修正⽅針(Recorder出⼒結果を参考に)
    以下のメソッドを切り出す(int引数は位置)
    71
    メソッド 概要
    goArticleList() 投稿⼀覧ページへ
    goFavsList() Fav⼀覧ページへ
    toggleFavStatus(int) Favボタンのトグル
    assertFavStatus
    (int, boolean)
    Favボタン状態確認
    assertItemExists(int) リストアイテム存在確認
    assertItemDoesntExist
    (int)
    リストアイテム不存在確認
    デモ

    View Slide

  72. テストケース実装
    さきほど定義したメソッドのみを使って、
    テストケースを実装する
    1. ☆をタップすると★に切り替わること
    2. ★をタップすると☆に切り替わること
    3. お気に⼊りが0件の状態で、☆をタップし
    て★にすると、お気に⼊り画⾯の表⽰件数
    が1件になること
    (1件⽬が存在し、2件⽬が存在しないこと)
    72
    デモ

    View Slide

  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

    View Slide

  74. 補⾜: Espresso-Commons
    今回紹介した⾃作ユーティリティだけ切
    り出したものを
    「Espresso-Commons」
    として公開しています。
    https://github.com/sumio/espresso-commons
    74

    View Slide

  75. ここまでのまとめ
    変更に強いテストコードを効率良く書く⽅
    法を実演を交じえて説明しました
    1. 「Espressoで簡単に記録できる or 書ける」
    という観点でテスト⾃動化対象を決める
    2. テストに必要な操作・検証をRecorderで
    1回だけ記録する
    3. 動かない出⼒を修正する
    4. 操作・検証単位でメソッド抽出する
    5. 抽出したメソッドのみを使ってテストを書く
    75

    View Slide

  76. 最後に
    変更に強いテストコードを効率良く書くに
    は、終盤で実演したアプローチに加えて、
    知識や経験(引き出しを増やす)も重要です。
    今回紹介したテクニックを⼟台に、まずは
    1つ書いてみることをおすすめします。
    ある程度軌道に乗ってから、
    「難易度が⾼いが効果も⾼い箇所」
    に挑戦するのがおすすめです。
    76

    View Slide

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

    View Slide