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
マネジメント視点でのre:Invent参加 ~もしCEOがre:Inventに行ったら~
kojiasai
0
460
Oracle Cloud Infrastructureデータベース・クラウド:各バージョンのサポート期間
oracle4engineer
PRO
27
12k
ガチ勢によるPipeCD運用大全〜滑らかなCI/CDを添えて〜 / ai-pipecd-encyclopedia
cyberagentdevelopers
PRO
3
200
AWSコンテナ本出版から3年経った今、もし改めて執筆し直すなら / If I revise our container book
iselegant
15
4k
プロダクトチームへのSystem Risk Records導入・運用事例の紹介/Introduction and Case Studies on Implementing and Operating System Risk Records for Product Teams
taddy_919
1
170
Figma Dev Modeで進化するデザインとエンジニアリングの協働 / figma-with-engineering
cyberagentdevelopers
PRO
1
430
話題のGraphRAG、その可能性と課題を理解する
hide212131
4
1.5k
Forget efficiency – Become more productive without the stress
ufried
0
110
初心者に Vue.js を 教えるには
tsukuha
5
390
現地でMeet Upをやる場合の注意点〜反省点を添えて〜
shotashiratori
0
520
生成AIとAWS CDKで実現! 自社ブログレビューの効率化
ymae
2
330
生成AIの強みと弱みを理解して、生成AIがもたらすパワーをプロダクトの価値へ繋げるために実践したこと / advance-ai-generating
cyberagentdevelopers
PRO
1
180
Featured
See All Featured
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
191
16k
Keith and Marios Guide to Fast Websites
keithpitt
408
22k
Code Reviewing Like a Champion
maltzj
519
39k
Stop Working from a Prison Cell
hatefulcrawdad
267
20k
Testing 201, or: Great Expectations
jmmastey
38
7k
[Rails World 2023 - Day 1 Closing Keynote] - The Magic of Rails
eileencodes
32
1.8k
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
231
17k
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
159
15k
Building Flexible Design Systems
yeseniaperezcruz
327
38k
XXLCSS - How to scale CSS and keep your sanity
sugarenia
246
1.3M
We Have a Design System, Now What?
morganepeng
50
7.2k
Fireside Chat
paigeccino
32
3k
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