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

Androidテスティング実践3 ユニットテスト・CI編

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

Androidテスティング実践3 ユニットテスト・CI編

NTTソフトウェア社内のソフト道場研修で実施した、Androidテスティング実践研修テキストの3. ユニットテスト・CI編です。

More Decks by NTTテクノクロス株式会社

Other Decks in Technology

Transcript

  1. Robolectricの特徴 ! Android向けユニットテストフレームワーク http://robolectric.org/ " MIT License ! Androidフレームワークの動作をJVMでエミュレーション " APIレベル16から21をエミュレート可能(3.0版現在) " 実⾏速度が速い ! Mockitoとの併⽤が可能 ! 広い範囲のエミュレーションサポート

    " ビューの展開、リソース取得、データベース操作、etc. " とはいえ、JVM上のエミュレーションに過ぎないことに注意 128 ビジネスロジックの検証がメインとなる ユニットテストでは⼗分使える Copyright © 2016, NTT Software Corporation. ※http://robolectric.org/ よりロゴを引⽤
  2. Robolectricのコンセプト ! ⾼速に実⾏できるLocal Unit Testの⽋点 (Android Framework APIが使えない) をRobolectricが克服 ! ユニットテスト・TDDで重要な 「開発のリズムを損わないサクサクさ」

    でAndroid APIが絡んだ部分のテスト実⾏が可能になる 129 Copyright © 2016, NTT Software Corporation. local JVM (Java SE) テストコード JUnitなど Android Framework API (空実装→Robolectric) プロダクトコード
  3. Robolectricの基本的な使い⽅(3/3) ! Shadowオブジェクト " AndroidフレームワークAPIの実装オブジェクト群 " Androidフレームワークが提供するクラスと1:1対応 ! Shadowオブジェクトの使いみち " Androidフレームワークでは提供されていないAPIを提供 " テストに有⽤な内部状態を知るためのAPIが中⼼ Copyright © 2016,

    NTT Software Corporation. 132 ImageView iv = (ImageView) activity.findViewById(.....); ShadowImageView shadow = Shadows.shadowOf(iv); ImageViewに対応するShadowオブジェクト ShadowImageView shadow = Shadows.shadowOf(iv); int resId = shadow.getImageResourceId(); 本来なら不可能な ImageViewの画像リソースIDにアクセス
  4. Robolectricの制限事項(1/2) ! Robolectric本体の制限事項 " 3.0版:API Level 21 (Android 5.0)までサポート " 3.1版:API Level 23

    (Android 6.0)までサポート ! targetSdkVersion=23では動作させるためには、 以下のいずれかの対応が必要 ※ https://github.com/robolectric/robolectric/issues/1932 参照 " robolectric.propertiesに「sdk=22」と追記する " build.gradleのdependenciesに、以下を追記する。 testCompile 'org.khronos:opengl-api:gl1.1-android-2.1_r1' ˞ compileSdkVersionとappcompat-v7のバージョンは 同じでなければならない点に注意! 133 Copyright © 2016, NTT Software Corporation.
  5. Robolectricの制限事項(2/2) 134 Copyright © 2016, NTT Software Corporation. プロジェクトのbuild.gradleファイル //

    (省略) android { // (省略) compileSdkVersion 21 // (省略) defaultConfig { // (省略) targetSdkVersion 21 // (省略) } // (省略) } dependencies { compile 'com.android.support:appcompat-v7:21.+’ // (省略) } 新規PJ作成時は最新verになっているの でcompileSdkVersionに合わせて修正
  6. Mockitoの紹介 特徴 " クラス定義から、そのクラスのスタブを⽣成できる " 実オブジェクトの⼀部メソッドの動作を変更できる " MIT License URL https://github.com/mockito/mockito (公式ホームページ) http://goo.gl/pOFyaQ

    (公式ドキュメント) http://tech.cm55.com/wiki/mockito/Manual (⽇本語紹介記事) 135 Copyright © 2016, NTT Software Corporation. ※https://github.com/mockito/mockito よりロゴを引⽤
  7. mockの概念 136 Copyright © 2016, NTT Software Corporation. Hoge mockHoge

    = mock(Hoge.class); Hoge hoge = new Hoge(); 例えば で⽣成したmockHogeは と違い ! メソッドの戻り値を事前に定義したり ! メソッドが呼ばれた事を後から確認したり できる
  8. spyの概念 137 Copyright © 2016, NTT Software Corporation. Hoge spyHoge

    = spy(new Hoge()); Hoge hoge = new Hoge(); 例えば で⽣成したspyHogeは と同じ実装を持ちつつ ! ⼀部のメソッドの戻り値を事前に定義したり ! メソッドが呼ばれた事を後から確認したり できる
  9. Mockitoの使い⽅ ! 基本 " モックの作成(mock) " メソッドの振る舞い変更(when, thenReturn, thenThrow) " メソッドが呼び出されたことを確認(verify) ! 実オブジェクトの振る舞い変更 " spyオブジェクト⽣成(spy) " メソッドの振る舞い変更(doReturn,

    doNothing, doThrow) ! 公式ドキュメントのコード例参照 (1) Let's verify some behaviour! (2) How about some stubbing? (12) doReturn()|doThrow()| doAnswer()|doNothing()| doCallRealMethod() family of methods (13)Spying on real objects 138 Copyright © 2016, NTT Software Corporation.
  10. Copyright © 2016, NTT Software Corporation. 139 【演習3-1】ユニットテスト環境構築 !  演習課題

    !  ユニットテスト対応 !  Robolectricのテストサンプル作成 !  テスト実⾏
  11. ユニットテスト対応(Gradle) 141 // (省略) dependencies { compile fileTree(dir: 'libs', include:

    ['*.jar']) // (省略) testCompile 'junit:junit:4.12' testCompile 'org.hamcrest:hamcrest-library:1.3' testCompile 'org.robolectric:robolectric:3.0' testCompile 'org.mockito:mockito-core:1.10.19' // (省略) } (挿⼊)必要なライブラリの宣⾔ 詳細は別途提⽰ Copyright © 2016, NTT Software Corporation. Moduleのbuild.gradleファイル
  12. Robolectricのテストサンプル作成(1/2) ! 以下のクラスを作成 (テスト対象クラス:EditActivity.javaのクラス名の上で Alt+Enter→Create Test) Copyright © 2016, NTT Software

    Corporation. 142 @RunWith(RobolectricGradleTestRunner.class) public class MyFirstRobolectricTest { private EditActivity activity; @Before public void setup() { activity = Robolectric.buildActivity(EditActivity.class).create().get(); } @Test public void testSomething() throws Exception { assertTrue(activity != null); } }
  13. (参考)Mavenのプロキシ設定 プロキシ配下で利⽤する場合は以下の設定も必要 ! 以下のディレクトリにsettings.xmlを配置する " Windows系: c:\Users\ユーザー名\.m2\ ! settings.xmlの内容は以下の通り Copyright © 2016, NTT

    Software Corporation. 145 <?xml version="1.0" encoding="UTF-8"?> <settings> <proxies> <proxy> <active>true</active> <protocol>http</protocol> <host>【プロキシのホスト名】</host> <port>【プロキシのポート番号】</port> </proxy> </proxies> </settings>
  14. ! AndroidのHTTP通信ライブラリOkHttpのサブコンポー ネントとして配布 https://github.com/square/okhttp/tree/master/mockwebserver ! Apache License Version 2.0 ! セットアップ⽅法 " build.gradleのdependenciesブロックに以下を記述 ! サーバの開始⽅法

    Copyright © 2016, NTT Software Corporation. 146 testCompile 'com.squareup.okhttp:mockwebserver:2.7.5' MockResponse response = ... (返して欲しいレスポンスを組み⽴てる) MockWebServer server = new MockWebServer(); server.enqueue(response); server.start(); URL mockServerUrl = server.url("/test").url(); URLのprefix(任意)を指定 (参考)MockWebServerについて(1/2)
  15. (参考)MockWebServerについて(2/2) ! MockResponse(返して欲しいレスポンス)組み⽴て⽅法 ! MockWebServer終了の⽅法(tearDown()で呼び出す) ! プロキシ設定の無効化(MockServer開始前に呼び出す) 環境により不要な場合もあり。環境への依存を下げるため書いておくのがベター。 Copyright © 2016, NTT Software

    Corporation. 147 MockResponse response = new MockResponse() // JSONのContent-Type指定 .addHeader("Content-Type", "application/json; charset=utf-8") .setResponseCode(HTTPレスポンスコード) .setBody(HTTPレスポンスボディ); server.shutdown(); System.clearProperty("proxyHost"); System.clearProperty("proxyPort");
  16. Jenkins ! 概要 " 広く使われているCIサーバ https://jenkins.io/ " MIT License ! 特徴 " インストールが簡単 ! コマンドライン1⾏でOK (java

    -jar jenkins.war) ! yumやapt-getでインストールすることも可能 " 設定が簡単 ! 全てWeb画⾯から設定できる Copyright © 2016, NTT Software Corporation. 156 ※https://github.com/jenkinsci/jenkins よりロゴを引⽤
  17. Android開発プロジェクトに適⽤する ! 前提条件 " Android StudioとGradleでプロジェクトが構築されていること " ソースコードがSubversionやGitで管理されており、 CIサーバからチェックアウトできること ! この研修で実現できる項⽬ " ビルド結果 " Android Lint結果

    " Local Unit Test結果 ! この研修では概要のみ触れる項⽬ " Instrumented Test結果 (エミュレータの起動が不安定、実⾏時間が⾮常に⻑くなるなどの 問題があるため、導⼊には試⾏錯誤が必要) Copyright © 2016, NTT Software Corporation. 157
  18. Android開発プロジェクトに適⽤する ! プラグインのインストール [Jenkinsの管理]→[プラグインの管理] " (★)Android Lint Plugin " Gradle plugin " Subversion plugin

    (ソースコードリポジトリがSubversionの場合) " Git plugin (ソースコードリポジトリがGitの場合) " JUnit plugin Copyright © 2016, NTT Software Corporation. 158 ˞ Jenkins 2.0からは、セットアップ時に「Suggested Plugins」を選択 していれば、★印のプラグインのみインストールすればOK
  19. Android開発プロジェクトに適⽤する ! 新規ジョブ作成 " 「フリースタイル・プロジェクトのビルド」を選択 " ソースコード管理 ! SubversionかGitを選択し、リポジトリのURLなどを⼊⼒ " ビルド・トリガ ! お好みで。迷ったら「SCMをポーリング」で良い " ビルド ! [ビルド⼿順の追加]→[Invoke Gradle

    script] ! [Use Gradle Wrapper]を選択 ! Tasksに[clean lint testDebugUnitTest]と⼊⼒ " ビルド後の処理 ! [ビルド後の処理の追加]→[Publish Android Lint results] ([Lint files]は空欄でOK) ! [ビルド後の処理の追加]→[JUnitテスト結果の集計] [テスト結果XML]に[app/build/test-results/debug/*.xml]と⼊⼒ Copyright © 2016, NTT Software Corporation. 160
  20. (参考)Instrumented Testも実⾏する場合 ! [Jenkinsの管理]→[プラグインの管理] " Android Emulator Pluginをインストールする ! ジョブの設定 " [ビルド環境]→[Run an Android

    emulator during build]にチェック ! 起動したいエミュレータの情報を⼊⼒ ! [Common emulator options]→[Show emulator window]はチェックし ない " [Invoke Gradle script]→[Tasks] ! [connectedAndroidTest]を追加 " [ビルド後の処理]→[JUnitテスト結果の集計] ! [テスト結果XML]を[app/build/**/TEST*.xml]に修正 Copyright © 2016, NTT Software Corporation. 161
  21. この研修で説明したこと ! ⾃動テストについての考え⽅ ! Androidのテストツール基礎知識 " Local Unit Test, Instrumented Test, ATSL, ...

    ! システムテスト⾃動化ツールの使い⽅ " Robotium, Espresso, UI Automator, Appium ! ユニットテスト⾃動化ツールの使い⽅ ! 各種テストは以下のテクニックを駆使して実現する " Android Studioのリファクタリング機能 " テスト⽤のメソッド・コンストラクタの追加 " Mockitoのmock()とspy() " MockWebServer ! CIの実現⽅法 Copyright © 2016, NTT Software Corporation. 163