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

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

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