Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

今更聞けない? Androidのテストのいろは

3,398 views

Published on

Android Test Night #2 でお話した(する)内容です。
https://testnight.connpass.com/event/69397/

Published in: Technology
  • Be the first to comment

今更聞けない? Androidのテストのいろは

  1. 1. 今更聞けない?Androidのテストの いろは @kikuchy
  2. 2. Who? ● @kikuchy ● 菊池 紘 ● 株式会社Diverse(ミクシィグループ) ● 一人で新規アプリ開発やってる最中です ● 求む、Androidエンジニア!!(iOSエンジニアも)
  3. 3. なんとなくテストしてきて幾星霜
  4. 4. よくわかってなかったこと ● 「実機で動かすテスト」って遅いイメージ。 本当に遅いのか? ● UIテスト、2年くらい前にAppiumに挑戦して挫折してそれっきり。 今時の始め方は? ● そもそもテストの種類ってどんなのがあって、 どうやって区別付けたら良いのか? ● この勉強会の内容かなり高度じゃないですか?
  5. 5. 基本に立ち返ろう
  6. 6. 目的 ● これからAndroidアプリのテストを始めたい方に、 どこから手を付けたら良いのか見当をつけていただく ● 理解がぼんやりしていた方に、はっきりとした理解をしていただく ● 識者に突っ込んでいただいて私が勉強し直す
  7. 7. 話さないこと ● テストランナー/フレームワークについて(JUnit4, JUnit5, Spek, etc) ● テストのための設計技法について(DI, MockやStub, etc) ● 自動テスト・手動テストの比較 ● 品質保証の技法
  8. 8. 区分
  9. 9. Androidのテストの種類 粒度実行場所 (開発マシンの)JVM Android (エミュレーター or 実機) 単体テスト/統合テスト Local Unit Test Instrumented Unit Test UIテスト ❌ Instrumented (UI) Test
  10. 10. Local Unit Test (1) ● JVMの上でテストを行う ● 「apk作って実機に送って…」という手順が必要ないので、 Instrumented Unit Testより結果が出るまでが早い ● Android frameworkの機能は使えない ○ frameworkはランタイムが提供しているものだから ○ 代わりに、APIのクラスやメソッドをスタブした android.jarを使用できる ○ メソッドは全てRuntimeExceptionを飛ばすスタブに置き換えられている ○ その代わり全てのクラスから final修飾子が外されている
  11. 11. Local Unit Test (2) ● AndroidランタイムのAPIを使う場合はモックする必要がある ○ 有名なモックライブラリが Robolectric ○ finalが外れているのでMockitoなどで自前でモックすることも可能
  12. 12. http://robolectric.org/
  13. 13. Robolectric ● Android frameworkのAPIモック実装とテストランナー類がセットになった便利ツー ル ● ほぼほぼ実機のAPIと同じように使える ○ SharedPreferencesにデータを記憶させることも可能 (一度テストが終わると内容は消える) ○ リソースも参照できる ○ 知っている限りでは、 AndroidKeyStoreは使用できなかった ● Activityのライフサイクルを試すようなことも可能
  14. 14. Robolectric導入 (1) // build.gradle android { testOptions { unitTests { includeAndroidResources = true } } } dependencies { testImplementation "org.robolectric:robolectric:3.5.1" }
  15. 15. Robolectric導入 (2) @RunWith(RobolectricTestRunner.class) public class ExampleRobolectricUnitTest { @Test public void testSaveInSharedPreferences() { // RuntimeEnvironment.application でApplication Contextを入手できる SharedPreferences sp = RuntimeEnvironment .application .getSharedPreferences("test", Context.MODE_PRIVATE); sp .edit() .putInt("hoge", 1) .apply(); Assert.assertEquals(sp.getInt("hoge", 0), 1); } }
  16. 16. http://site.mockito.org/
  17. 17. Mockito (1) ● 昔から有名なJavaのモックライブラリ ● あるインスタンスの特定のメソッドを呼んだら事前に設定した値を返す、 というモックインスタンスを生成することが可能 ○ DIのためにinterfaceを用意しておくことがあるが、 Mockitoがあればinterfaceを用意しなくても済む ケースが多い
  18. 18. Mockito (2) ● Mockito 2.1.0からはfinalクラスをモックするオプションもある ○ Kotlinで宣言したクラスは基本的に finalなので、これがないと非常にきつい ○ org.mockito:mockito-inline をdependenciesに追加すると有効になる ● Kotlinでテストを書く場合はMockito-Kotlinを使うと良い ○ when()を書く場合にバッククォートしないといけなくなるの避け ○ 他にも便利な関数がたくさん
  19. 19. Mockito導入 (1) // build.gradle dependencies { testImplementation "com.nhaarman:mockito-kotlin-kt1.1:1.5.0" testImplementation "org.mockito:mockito-inline:2.8.9" }
  20. 20. Mockito導入(2) @Test fun testWithMock() { val dependee: Dependee = mock { // Mockito-Kotlin は mock {} でモックの設定ができる on { doSomething() }.then { Result(1) } } val depending = Depending(dependee) val actual = depending.doAnotherThingWithSomething() assertEquals(Result(1), actual) }
  21. 21. Instrumented Unit Test ● Googleは結合テストの段階ではAndroidの上でテストすることを推奨している ● Test Support Libraryを導入して RunWithアノテーションを書いて androidTestディレクトリ以下にテストコードを置けば良いだけ ● 普通のUnitテストとほぼ何も変わらない
  22. 22. Instrumented Unit Testの例 @RunWith(AndroidJUnit4::class) class ExampleInstrumentedTest { @Test fun testSaveSharedPreferences() { val sp = InstrumentationRegistry .getTargetContext() .getSharedPreferences("hoge", Context.MODE_PRIVATE) sp .edit() .putInt("hoge", 1) .apply() assertEquals(sp.getInt("hoge", 0), 1) } }
  23. 23. Instrumented UI Test ● 実機やエミュレーター上のアプリ操作と検証を自動で行う ● 画面操作のフレームワークが必要 ○ 自アプリだけで完結する場合は Espresso ○ 他アプリとの連動が必要な場合は UI Automator ● 必要なものはTest Support Libraryにだいたい入っている ● WebやiOSと画面構成が同じならAppiumを使う手もある ○ Java/Kotlin以外でテストを書きたい場合も選択肢に入る
  24. 24. Espresso (1) ● Viewの取得、操作とアサーションの仕組みを提供するフレームワーク ● Viewを指定して操作を伝え、期待した結果を引き起こせたか確認するのが基本手 順 ● 「ダイアログが表示されるまで待つ」とかは自動でやってくれる模様 ● 3.0からパーミッションダイアログをスキップするなども可能になった
  25. 25. Espresso (2) ● 面倒なDatePickerなどの操作を簡略化してくれる espresso-contribなど、補助ライブラリも充実している ● Android StudioのEspresso Test Recorderを使うと デバイス上の操作をコードに落としてくれる ○ 詳しくは外山さんのDroidkaigi 2017のセッションを参照 https://academy.realm.io/jp/posts/droidkaigi17-espresso-test/
  26. 26. UI Automator ● デバイス状態の変更が可能 ○ 画面回転 ○ 通知欄を開く ○ ホームボタンやバックボタンなどを押下する ○ スクリーンショットを撮る ○ などなど ● 上記組み合わせで、自アプリ以外のアプリも操作する事が可能 ○ 外部アプリとの連携のテストは Espressoではできない ○ Settingsから通知設定をいじったりパーミッションを変更したり、といったテストも可能 ● Espressoと組み合わせて使用することもできる ○ 画面回転させてから操作、ということも可能
  27. 27. DEMO (時間があれば)
  28. 28. Appium ● SeleniumのiOS/Android対応版 ● Driver経由でデバイスを操作するためのもの ● WebDriver JSON Wire Protocolを喋るならどの言語でテストを書いても良い ● 中ではUI Automatorを使っているらしい ● 2年前にこれでテストを書こうとしてツラミウムになったのでそれ以来触ってないです
  29. 29. 知っておくと便利なこと
  30. 30. 遠隔実機提供サービス ● 手元にない種類の実機でテストをしたいときなどに使う ● 主に以下の2つが有名 ○ Firebase Test Lab for Android ■ Instrumented Testだけでなく、botがなんかいい感じに UI操作してくれるRoboテストというも のもある ■ Android Studioから実行して結果を見ることが可能 ○ AWS Device Farm ■ 対応デバイス/OSバージョンの種類が多い ■ リモートデバイスをブラウザから操作可能 ● 自前で同じようなものを作ることも可能 ○ Open STF
  31. 31. CIサービスのInstrumented Test対応 ● CIサービスによってはInstrumented Test可能なところがある ○ Bitrise ■ 立ち上げ済みのエミュレーターがいるので、テスト用 APKを投げると実行してくれる ○ CircleCI ■ Android SDKインストール済みイメージにはエミュレーターが入っているので、 自力でエミュレーターを立ち上げれば可能
  32. 32. 宣伝 ● DiverseではAndroid(Kotlin, Java), iOS(Swift), サーバー(Ruby, Kotlin) 開発ができるエンジニアを募集中です ● 特に新規事業のiOS開発チームリーダー募集に注力中 ● 自分の力でサービスを成長させることに興味がある方、 お話させてください! DM to @kikuchy or https://diverse-inc.co.jp/recruit/

×