Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Androidテスティング実践3 ユニットテスト・CI編
Search
NTTテクノクロス株式会社
July 22, 2016
Technology
0
290
Androidテスティング実践3 ユニットテスト・CI編
NTTソフトウェア社内のソフト道場研修で実施した、Androidテスティング実践研修テキストの3. ユニットテスト・CI編です。
NTTテクノクロス株式会社
July 22, 2016
Tweet
Share
More Decks by NTTテクノクロス株式会社
See All by NTTテクノクロス株式会社
NTT TechConference #2 Closing Keynote
ntttechnocross
4
2.5k
僕らはStackStormをどう使うべきか / NTT TechConference #2 StackStorm
ntttechnocross
1
3.3k
ネットワークスイッチ構築実践 2.STP・RSTP・PortSecurity・StormControl・SPAN・Stacking編
ntttechnocross
0
310
ネットワークスイッチ構築実践 1.VLAN・LinkAggregation編
ntttechnocross
0
340
ネットワーク構築訓練入門
ntttechnocross
1
240
Androidテスティング実践 基礎編
ntttechnocross
2
310
Androidテスティング実践2 システムテスト編
ntttechnocross
1
300
WebRTC Training
ntttechnocross
0
300
Androidアプリケーション開発中級研修 前編
ntttechnocross
2
510
Other Decks in Technology
See All in Technology
新卒1年目が挑む!生成AI × マルチエージェントで実現する次世代オンボーディング / operation-ai-onboarding
cyberagentdevelopers
PRO
1
160
ABEMA のコンテンツ制作を最適化!生成 AI x クラウド映像編集システム / abema-ai-editor
cyberagentdevelopers
PRO
1
180
とあるユーザー企業におけるリスクベースで考えるセキュリティ業務のお話し
4su_para
3
320
AIを駆使したゲーム開発戦略: 新設AI組織の取り組み / sge-ai-strategy
cyberagentdevelopers
PRO
1
130
「視座」の上げ方が成人発達理論にわかりやすくまとまってた / think_ perspective_hidden_dimensions
shuzon
2
130
Oracle Base Database Service 技術詳細
oracle4engineer
PRO
5
49k
Commitment vs Harrisonism - Keynote for Scrum Niseko 2024
miholovesq
6
1.1k
小規模に始めるデータメッシュとデータガバナンスの実践
kimujun
3
580
ガバメントクラウド先行事業中間報告を読み解く
sugiim
1
1.2k
クライアントサイドでよく使われる Debounce処理 をサーバサイドで3回実装した話
yoshiori
1
150
Autify Company Deck
autifyhq
1
39k
VPC間の接続方法を整理してみた #自治体クラウド勉強会
non97
1
820
Featured
See All Featured
Optimising Largest Contentful Paint
csswizardry
33
2.9k
Fireside Chat
paigeccino
32
3k
Navigating Team Friction
lara
183
14k
Done Done
chrislema
181
16k
Cheating the UX When There Is Nothing More to Optimize - PixelPioneers
stephaniewalter
280
13k
Mobile First: as difficult as doing things right
swwweet
222
8.9k
Git: the NoSQL Database
bkeepers
PRO
425
64k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
246
1.3M
Designing for humans not robots
tammielis
249
25k
"I'm Feeling Lucky" - Building Great Search Experiences for Today's Users (#IAC19)
danielanewman
226
22k
Code Reviewing Like a Champion
maltzj
519
39k
Fontdeck: Realign not Redesign
paulrobertlloyd
81
5.2k
Transcript
Androidテスティング実践 ③ユニットテスト・CI編
本スライドは、NTTソフトウェア社内技術者育成研修(ソフト道場研修)テキストです。 【著作権・免責事項】 ! 本セミナーコースの内容、本資料のすべての著作権は、NTTソフトウェア株式会社に帰属します。 ! 無断での本資料の複写、複製、再利⽤、転載、転⽤を禁じます。 ! 本資料と演習等で利⽤するすべての教材は、NTTソフトウェア株式会社からの保証なしに提供されます。 ! 本書に記載されている会社名および製品名は、⼀般に各社の商標または登録商標です。
Copyright © 2016, NTT Software Corporation. 120 ˞ 演習問題に関するスライドは、⼀部を除き、本ファイルには含まれておりません。 また、演習に必要なソースコードも含まれておりません。ご了承ください。
3. ユニットテスト⾃動化 ! ユニットテストについて ! ツールの概要 ! ユニットテスト⾃動化で⼤事なこと ! プロダクトコードのテスト容易性
! 「レガシーコード」改善 121 Copyright © 2016, NTT Software Corporation.
Copyright © 2016, NTT Software Corporation. 122 ユニットテストについて
ユニットテストとは(1/2) ! 位置付け " 開発者が安⼼するためのテスト(Developer Test) " プロダクトがデグレしないようにするためのセーフティネット " 品質向上には寄与するが、品質保証が第⼀⽬的ではない ! 書くタイミング " プロダクトコードを書きながらテストも書く プロダクトコード完成後ではない ! テスト対象
" ビジネスロジック " 開発者が実装していて不安なところ " 画⾯(GUI)の試験は対象外とすることが多い 123 Copyright © 2016, NTT Software Corporation.
ユニットテストとは(2/2) テストを成功状態にしたままリファクタリングする テストを失敗から成功に変化させるようにテスト対象コードを書く テストを失敗させるテストコードを追加する テストを失敗から成功に変化させるようにテスト対象コードを書く 失敗するテストコードを書く Copyright © 2016, NTT
Software Corporation. 124 ! (参考)TDD (テスト駆動開発)について http://www.atmarkit.co.jp/ait/articles/1403/05/news035.html
プロダクトコードの「テスト容易性」 テスト容易性=テストが書き易いプロダクトコード ! テストしたいロジックはActivityに書かない ! (匿名)内部クラス禁⽌ " リスナやAsyncTaskは普通のクラスにする。 必要なものはコンストラクタで受け取れば良い。 ! テスト⽤にフィールドを差し替えられるように " 「パッケージプライベート」なsetterやコンストラクタを 必要に応じて⽤意。 " テスト時にoverrideしたいメソッドをパッケージプライベートに。
" 「本来privateだがテストコードからはアクセスさせたいもの」は 「パッケージプライベート」で。 " テストはプロダクトと同じパッケージに置く。 Copyright © 2016, NTT Software Corporation. 125
「レガシーコード」改善 レガシーコード = テストが無いコード テストが無く仕様変更時に⼿がつけられないコード ! レガシーコード改善 " ⾃動ユニットテストでカバーしてから改造(変更)する " そのままだとテストが書けない場合 ! テストが書けるように、必要最低限の改造をする " デグレしないように、IDEのリファクタ機能を駆使する
(⼿動で変更しない) " フィールド/メソッド/クラス追加やアクセス修飾⼦変更はOK ! 参考書籍「レガシーコード改善ガイド」 http://www.amazon.co.jp/dp/4798116831 126 Copyright © 2016, NTT Software Corporation.
Copyright © 2016, NTT Software Corporation. 127 ツールの概要 ! Robolectric
! Mockito
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/ よりロゴを引⽤
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) プロダクトコード
Robolectricの基本的な使い⽅(1/3) ! 基本はJUnit4 ! テストランナーを指定する(@RunWithアノテーション) ! テストの前提条件を指定する(@Configアノテーション) " constantsの指定は必須(Robolectricがgradleの情報を得るため) " その他、エミュレートしたいAPIレベルの指定なども可能。 http://robolectric.org/configuring/ 130 @RunWith(RobolectricGradleTestRunner.class) @Config(constants
= BuildConfig.class) Copyright © 2016, NTT Software Corporation.
Robolectricの基本的な使い⽅(2/3) ! @RunWithと@Configをまとめて書くと ! @Configは設定ファイルに書いても良い(おすすめ!) " ファイル名: src/test/resources/robolectric.properties 131 @Config(constants = BuildConfig.class) @RunWith(RobolectricGradleTestRunner.class)
public class MyFirstRobolectricTest { .... } constants=[パッケージ名].BuildConfig Copyright © 2016, NTT Software Corporation.
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にアクセス
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.
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に合わせて修正
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 よりロゴを引⽤
mockの概念 136 Copyright © 2016, NTT Software Corporation. Hoge mockHoge
= mock(Hoge.class); Hoge hoge = new Hoge(); 例えば で⽣成したmockHogeは と違い ! メソッドの戻り値を事前に定義したり ! メソッドが呼ばれた事を後から確認したり できる
spyの概念 137 Copyright © 2016, NTT Software Corporation. Hoge spyHoge
= spy(new Hoge()); Hoge hoge = new Hoge(); 例えば で⽣成したspyHogeは と同じ実装を持ちつつ ! ⼀部のメソッドの戻り値を事前に定義したり ! メソッドが呼ばれた事を後から確認したり できる
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.
Copyright © 2016, NTT Software Corporation. 139 【演習3-1】ユニットテスト環境構築 ! 演習課題
! ユニットテスト対応 ! Robolectricのテストサンプル作成 ! テスト実⾏
演習課題 ! 以下作業を通じて、テスト環境構築の⽅法を習得 してください。 " Android Studio上でアプリを新規作成する " ビルドスクリプトを修正してRobolectric + Mockito 対応にする " Robolectricのテストサンプルを追加し、実⾏してみる
Copyright © 2016, NTT Software Corporation. 140
ユニットテスト対応(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ファイル
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); } }
Robolectricのテストサンプル作成(2/2) ! robolectric.propertiesファイル作成 Copyright © 2016, NTT Software Corporation. 143
constants=[パッケージ名].BuildConfig
! コマンドラインからの実⾏ " Instrumented Testを実⾏する場合(端末を接続した状態で) " Local Unit Test(今回のRobolectric)を実⾏する場合 ! Android Studioからの実⾏ " テストしたいメソッドやクラスを選択して右クリック→[Run] (Ctrl+Shift+F10)
※Preferences→keymap→Run context configuration テスト実⾏ 144 gradlew connectedAndroidTest gradlew test Copyright © 2016, NTT Software Corporation. テストコードが緑に なっている
(参考)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>
! 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)
(参考)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");
Copyright © 2016, NTT Software Corporation. 148 テスト対象アプリの解説
Copyright © 2016, NTT Software Corporation. 149 【演習3-2,3】ビジネスロジックのテスト
Copyright © 2016, NTT Software Corporation. 150 【演習3-4】イベントリスナのテスト
Copyright © 2016, NTT Software Corporation. 151 【演習3-5】 HTTP通信を伴うメソッドのテスト
Copyright © 2016, NTT Software Corporation. 152 【演習3-6】 データベースアクセスのテスト
4. CIの実現 ! CIの概要 ! Android開発プロジェクトに適⽤する ! (参考)Instrumented Testも実⾏する場合 Copyright
© 2016, NTT Software Corporation. 153
CIとは ! 継続的インテグレーション(Continuous Integration) ! ⾃動的に以下を実施してくれる " リポジトリから最新のソースコード⼀式を取得 " ビルドや⾃動テストなど実⾏し、その結果を通知 Copyright © 2016, NTT
Software Corporation. 154 通常は専⽤の サーバで動かす
CIのメリット ! ビルド・テストに失敗するコードがコミットされたとき に、いち早く検知し、対策を打つことができる。 ! Androidのように、ビルドや全テスト実⾏に時間がかかる 場合でも、CIサーバに全てお任せすれば、⽣産性向上に つながる。 Copyright © 2016, NTT
Software Corporation. 155
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 よりロゴを引⽤
Android開発プロジェクトに適⽤する ! 前提条件 " Android StudioとGradleでプロジェクトが構築されていること " ソースコードがSubversionやGitで管理されており、 CIサーバからチェックアウトできること ! この研修で実現できる項⽬ " ビルド結果 " Android Lint結果
" Local Unit Test結果 ! この研修では概要のみ触れる項⽬ " Instrumented Test結果 (エミュレータの起動が不安定、実⾏時間が⾮常に⻑くなるなどの 問題があるため、導⼊には試⾏錯誤が必要) Copyright © 2016, NTT Software Corporation. 157
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
Android開発プロジェクトに適⽤する ! [Jenkinsの管理]→[システムの設定] ! [Jenkinsの管理]→[Global Tool Configuration] " 原則デフォルト設定のままでOK " 既にインストールされているJDKやgitなどを 利⽤したい場合はそのパスを指定しても良い。 Copyright ©
2016, NTT Software Corporation. 159
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
(参考)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
まとめ Copyright © 2016, NTT Software Corporation. 162
この研修で説明したこと ! ⾃動テストについての考え⽅ ! 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
最後に ! プロダクトコードを⾃動化したユニットテストで カバーすることで、ソース修正時の安⼼感が劇的に上がります。 ! 既にレガシーコードがある場合は、全部やろうとせず、 CIやユニットテストから少しずつ始めて⾏くと良いでしょう。 " テストが全く無くても、CIだけ始めてみる。 ! Android Studioに移⾏するだけで始められます。 " 新しく機能追加したところだけでもテストを書いてみる。 ! リリースを何度も⾏うプロジェクトでは、
システムテスト⾃動化にもチャレンジしてみてください。 Copyright © 2016, NTT Software Corporation. 164
おわり お疲れ様でした
https://www.ntts.co.jp/products/soft_dojyo/index.html