Androidテスティング実践
①基礎編
本スライドは、NTTソフトウェア社内技術者育成研修(ソフト道場研修)テキストです。
【著作権・免責事項】
 本セミナーコースの内容、本資料のすべての著作権は、NTTソフトウェア株式会社に帰属します。
 無断での本資料の複写、複製、再利用、転載、転用を禁じます。
 本資料と演習等で利用するすべての教材は、NTTソフトウェア株式会社からの保証なしに提供されます。
 本書に記載されている会社名および製品名は、一般に各社の商標または登録商標です。
Copyright © 2016, NTT Software Corporation. 2
※ 演習問題に関するスライドは、一部を除き、本ファイルには含まれておりません。
また、演習に必要なソースコードも含まれておりません。ご了承ください。
本研修の対象者・受講条件
対象者
Androidアプリのユニットテスト自動化に興味があるが、
どこから手を付けて良いかわからない方
Androidのユニットテストを書き始めてみたが、様々な理由で
途中で諦めてしまった(または諦めてしまいそうな)方
Androidのシステムテスト(UI部分)の自動化
に踏み出してみたい方
受講条件
Androidアプリケーション開発の入門知識、および、
Javaプログラミングの経験を有していること
JUnitの利用経験があること
Copyright © 2016, NTT Software Corporation. 3
本研修の講義目的と到達目標(1/3)
4Copyright © 2016, NTT Software Corporation.
Androidアプリ開発プロジェクトで
• 実際の開発で無理なくユニットテストコードが書ける
• システム(UI)テスト自動化ツールについて
• 「どんな場面でどのツールを使えば良いか」分かる
• 簡単なテストシナリオを自動化できる
本研修の講義目的と到達目標(2/3)
5Copyright © 2016, NTT Software Corporation.
学習すること
自動ユニットテストの位置付けとメリット
Androidアプリのユニットテストの書き方
Android Studio、Robolectric、Mockitoを利用します
ありがちなシーン別に演習中心に学習します
システムテスト自動化ツールの特徴と
基本的なテストスクリプトの書き方
【座学+演習】Robotium、Espresso、UI Automator
【座学のみ】Appium
本研修の講義目的と到達目標(3/3)
6Copyright © 2016, NTT Software Corporation.
本研修で取り上げないこと
Android標準のユニットテスト
システムテスト自動化ツールの詳しい使い方
この研修のカバー範囲
Copyright © 2016, NTT Software Corporation. 7
ユニットテスト
自動化スキル
システムテスト
自動化スキル
色々なツールを広く薄く
実アプリに対するテストコードが
書けるレベルまで深く修得
本研修の講義内容
8
1日目 2日目
午前
9:30〜
12:00
 Androidテスティング基礎
 自動テストについての考え方
 テストアーキテクチャ
(演習あり)
 ユニットテストの自動化
 基本的な使い方
 ビジネスロジックのテスト
(演習あり)
昼休憩 12:00〜13:00
午後
13:00〜
17:30
 システムテストの自動化
 Robotium (演習あり)
 Espresso (演習あり)
 UI Automator (演習あり)
 Appium
 イベントリスナのテスト
(演習のみ)
 HTTP通信を行うメソッド
のテスト (演習のみ)
 DBアクセスするメソッドの
テスト (演習のみ)
 CI
※60〜90分ごとに適宜休憩を入れます
Copyright © 2016, NTT Software Corporation.
本研修で紹介するツール
9
ツール名 概要
JUnit4 単体テストフレームワーク
Robotium 直感的に書けるのが特徴のUIテストフレームワーク
Espresso White-boxテストができるUIテストフレームワーク
UI Automator アプリにまたがったテストができる
UIテストフレームワーク
Appium Seleniumと似たAPIを持つUIテストフレームワーク
Robolectric 通常のJVM上でAndroidの単体試験を
実施するためのフレームワーク
Mockito モッククラスを簡単に作成するためのライブラリ
Android Studio Android向けの新しい統合開発環境
Gradle Android標準となったGroovyベースのビルドツール
Copyright © 2016, NTT Software Corporation.
1. Androidテスティング基礎
 自動テストについての考え方
 Androidの開発環境
 Local Unit TestとInstrumented Test
 JUnit4とAndroid Testing Support Library
 テスト対象アプリの紹介
10Copyright © 2016, NTT Software Corporation.
Copyright © 2016, NTT Software Corporation. 11
自動テストについての考え方
【考え方】テスト自動化のメリット(1/2)
1. 新版リリース時に、既存の回帰テストを自動実行できる
間違った修正をすればテストに失敗する(デグレ防止)
安心してソースコードの整理(リファクタリング)・改造ができる
2. テストをもっと頻繁に、たくさん実行できる
3. 手動では困難・不可能なテストができる
4. 人的リソースの有効活用
テスト担当者はより良いテストケース設計に注力できる
CI (Continuous Integration) ツールと連携すれば、
自動テストの定期的な実行ですら機械任せにできる。
Copyright © 2016, NTT Software Corporation. 12
(参考)Mark Fewster, Dorothy Graham著「システムテスト自動化標準ガイド」(翔泳社) 第1章
【考え方】テスト自動化のメリット(2/2)
5. テストの一貫性と再現性
同一のテストを異なるデバイス上で実行できる
6. テストの再利用
何度もテストを実行することで、
初期コスト(テスト設計、実装など)を分散できる
7. 市場に早く提供できる
8. 自信が持てる
Copyright © 2016, NTT Software Corporation. 13
(参考)Mark Fewster, Dorothy Graham著「システムテスト自動化標準ガイド」(翔泳社) 第1章
【考え方】テスト自動化に共通する問題
1. 自動テストツールの採用で全て解決すると思ってしまう
2. ダメなテストの自動化してしまう
ダメなテストを自動化してもダメなまま
3. 自動テストは新しいバグを発見しない
自動テストスクリプトを書く段階で新規バグは見つかる!
4. 自動テストを全てパスしても、バグは存在する
5. 自動テストのメンテナンスコストが高くなる
テスト対象が仕様変更する度に、テストスクリプトの修正が必要
6. 自動テストツールにバグがある
7. 組織のサポートが得られない
「初回は導入コストが大きいため、ほとんど利益は得られない」
ことを上司に分かってもらう必要がある
Copyright © 2016, NTT Software Corporation. 14
(参考)Mark Fewster, Dorothy Graham著「システムテスト自動化標準ガイド」(翔泳社) 第1章
【考え方】どうすれば良いのか(1/4)
Copyright © 2016, NTT Software Corporation. 15
自動化の目的は効率化
手作業を繰り返すよりもコスト(稼働)が減る
 「自動化」には自動化するためのコスト
がかかる
 学習コスト
 最初にテストコードを書くコスト
 改造時にメンテし続けていくコスト
自動化すべき箇所はどこ?
【考え方】どうすれば良いのか(2/4)
自動化すべき箇所
テストコードが簡単に(少ない稼働で)書けるところ
イニシャルコストが少なくて済む
何度も繰り返しテストするところ
繰り返すほどペイする
改造しても仕様があまり変わらないところ
テストコードの修正稼働が少なくて済む
Copyright © 2016, NTT Software Corporation. 16
まずはここからはじめよう
【考え方】どうすれば良いのか(3/4)
ツール選定の考え方
「やりたいことが簡単にできるかどうか」が重要
ありがちなアンチパターン
1つのツールで全部やろうとする
全てのテストを自動化しようと頑張る
おすすめ!
複数ツールを併用する。
そのツールが得意なところだけ活用する。
テストクラス単位でのツール選択OK
簡単に書けるところだけ自動化する
Copyright © 2016, NTT Software Corporation. 17
【考え方】どうすれば良いのか(4/4)
ユニットテスト vs システム(UI)テスト
(原則)ユニットテスト自動化から着手すべき
ソース変更の度に再テストできるので効果が高い
改造時に最低限の品質が担保できる
テストを書くことで、曖昧だった仕様が明確になる
(例)引数にnullを指定したらどうなるか?
事情によってはシステムテスト自動化からでもOK
どちらに稼働がかかっているか?
何度もやるはめになっているのはどちらか?
Copyright © 2016, NTT Software Corporation. 18
全部自動化しようと思わないこと!
【考え方】ユニットテスト自動化で大事なこと(1/2)
サクサク実行できること
開発者はコードを書きながらテストも書く
テストの実行に時間がかかると効率が落ちてしまう
モックライブラリが使えること
簡単にテストを書くにはモックライブラリは必須
意味のあるテストを自動化すること
コスト的に見合うか考える
GUIや非同期処理など、大変すぎる箇所はやらない
→後フェーズで手動でテストすれば良い
ミスが入りそうな複雑なロジックのテストを優先する
単純なsetter/getterのテストを沢山書く意義は薄い
19Copyright © 2016, NTT Software Corporation.
【考え方】ユニットテスト自動化で大事なこと(2/2)
ユニットテスト自動化ツールは、
以下の組み合わせがおすすめ(詳細は第4章で)
Mockito: モックライブラリの定番
Robolectric: サクサク実行できる!
Copyright © 2016, NTT Software Corporation. 20
【考え方】システムテスト自動化で大事なこと
テストスクリプトが簡単に書けること
UIは移ろいやすい
UI変更により作り直してもダメージが少ない
UI変更に強いテストコード設計にすること
Page Objectパターンは必須!
(参考)「4時間で学ぶ、効率的な自動テストスクリプトのメンテナンス」
https://goo.gl/PTdOfB (テスト自動化研究会 チュートリアル資料)
簡単に自動化できるテスト項目に絞ること
テストツールによって得手不得手がある
各テストツールの得意な部分をつまみ喰いする
例外: (自動化コスト以上に)手動でのテストが面倒な場合
Copyright © 2016, NTT Software Corporation. 21
【考え方】(参考)Android特有の試験観点(1/3)
Activityのライフサイクルイベントに関する試験
onPause()、onCreate()でのデータの永続化・復元
特にホームキーが押下された時の振る舞いは見落しがち!
画面の向きが変わった時の動作 (onConfigurationChanged())
ネットワーク通信やDB操作などの重い処理に関する試験
ANR (Application Not Responding) エラーが発生しないか
データベース・ファイルシステム操作に関する試験
UIの細かい振る舞いに関する試験
UIコンポーネントの押下時/非押下時、選択時/非選択時の色
キーによるフォーカス移動の順番
etc.
Copyright © 2016, NTT Software Corporation. 22
(参考)Diego Torres Milano著「Android Application Testing Guide」(Packt Publishing)
【考え方】(参考)Android特有の試験観点(2/3)
機種に依存する振る舞いに関する試験
ネットワーク接続の種類・状況の違い
画面密度、解像度、物理的なサイズの違い
各種センサー(加速度センサーなど)のサポート状況の違い
入力デバイス(キーボードなど)の違い
etc
Copyright © 2016, NTT Software Corporation. 23
(参考)Diego Torres Milano著「Android Application Testing Guide」(Packt Publishing)
【考え方】(参考)Android特有の試験観点(3/3)
公式ドキュメント: Core App Quality Guidelines
http://developer.android.com/distribute/googleplay/quality/core.html
4つの観点 (※)
Visual Design and User Interaction
Functionality
Performance and Stability
Google Play
Test Procedure
CR-0: 全部の画面やダイアログについて、実際に遷移させてみる
CR-1: 全部の画面について、
ホームキーを押してから再度アプリを起動してみる
CR-2: 全部の画面について、別アプリに切り替えてから、
元のアプリに戻してみる
etc.
Copyright © 2016, NTT Software Corporation. 24
※ 具体例は、書籍「Androidアプリテスト技法」p.197参照
http://www.amazon.co.jp/dp/4798037044
Copyright © 2016, NTT Software Corporation. 25
Androidの開発環境
Androidの新しい開発環境: Android Studio
概要
「Google I/O 2013」で発表された、
新しいAndroid向け統合開発環境
IntelliJ IDEA Community Editionから派生
インストール
http://developer.android.com/sdk/index.html
インストーラが立ち上がるので、指示通りに進める
「Android Studioセットアップガイド」が参考になる
https://keiji.github.io/the-androidstudio-book/
26Copyright © 2016, NTT Software Corporation.
※Eclipse+ADTは2015年12月で公式サポートが打ち切られました
Android Studioの特徴
ビルド環境の一元化
GUIからもコマンドライン(Gradle)からも同一バイナリ
を生成できる
Mavenベースの依存関係解決システム
ビルド設定ファイルに1行書くだけでOSSが利用できる
ビルドバリアントサポート
機能の大部分は同じだが、一部だけ振る舞いの異なる
ような、複数のアプリケーションを開発できる
Copyright © 2016, NTT Software Corporation. 27
Android Studioの動作環境
RAM: 最低2GB、推奨8GB
HDD: 最低2GB、推奨4GB (Android SDK含む)
解像度: 最低1280×800
Java: JDK8最新版 (JAVA_HOME環境変数)
CPU: 以下の機能を搭載していること
Intel VT-x
Intel EM64T (Intel 64)
Execute Disable (XD) Bit
28Copyright © 2016, NTT Software Corporation.
Android Studioの初期設定
プロキシ設定
[Configure]→[Settings]→[HTTP Proxy]
C:¥Users¥ユーザー名¥.gradle¥gradle.properties
文字コード設定
[Configure]→[Settings]→[Editor]→[File Encoding]
3箇所全て「UTF-8」にする
29Copyright © 2016, NTT Software Corporation.
Android Studioでプロジェクト作成/インポート
30
新規プロジェクト作成
Eclipseのプロジェクトをインポート
Copyright © 2016, NTT Software Corporation.
ソースコードのディレクトリ構成
31
Projectの中に
Module(アプリ本体)がある
テストコード①
プロダクトコード
Moduleのビルド定義ファイル
Projectのビルド定義ファイル
Copyright © 2016, NTT Software Corporation.
テストコード②
Android Studioの
Projectビューで確認する
Android Studioで良く使うショートカット
行の補完: Ctrl+Shift+Enter
コンテンツアシスト: Ctrl+SPC
テストの実行: Ctrl+Shift+F10
コードフォーマット: Ctrl+Alt+L
選択行の移動: Alt+Shift+↑↓
選択行の複製: Ctrl+D
テストメソッドの生成など: Alt+Insert
インテンション(EclipseのCtrl+1): Alt+Enter
Find Action: Shift2回押し
Copyright © 2016, NTT Software Corporation. 32
※ [File]>[Settings...]>[Keymap]で好みのショートカットに
変更できます。
Copyright © 2016, NTT Software Corporation. 33
Local Unit TestとInstrumented Test
Androidが用意しているテストの仕組み(1/2)
Local Unit Test
 JVM上(開発マシン上)で動作
高速だが実環境ではない
Android Framework APIは原則呼び出せない
(Robolectricを使えば可能。2日目に説明します。)
Copyright © 2016, NTT Software Corporation. 34
local JVM (Java SE)
テストコード
JUnitなど Android Framework API (空実装)
プロダクトコード
※ 用語の定義は https://developer.android.com/training/testing/start/index.html
を参考にしています
Androidが用意しているテストの仕組み(2/2)
Instrumented Test
Android上で動作する
実環境で動作するが、遅い
Android Framework API
呼び出しOK
Copyright © 2016, NTT Software Corporation. 35
(出典) https://developer.android.com/studio/test/index.html#Instrumentation
テストコードの配置
36
プロダクトコード
(src/main)
Copyright © 2016, NTT Software Corporation.
Instrumented Test
(src/androidTest)
Local Unit Test
(src/test)
app/build.gradleについて
dependenciesブロックの書き方に注意
Copyright © 2016, NTT Software Corporation. 37
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile 'commons-io:commons-io:2.5'
androidTestCompile 'com.android.support.test:runner:0.5'
testCompile 'org.robolectric:robolectric:3.0'
}
プロダクトコードで使うもの
(compile)
Instrumented Testで使うもの
(androidTestCompile)
Local Unit Testで使うもの
(testCompile)
コマンドラインからの実行
Instrumented Testを実行する場合(端末を接続した状態で)
Local Unit Test を実行する場合
Android Studioからの実行
テストしたいメソッドやクラスを選択して右クリック→[Run]
(Ctrl+Shift+F10) ※Preferences→keymap→Run context configuration
テストの実行
38
gradlew connectedAndroidTest
gradlew test
Copyright © 2016, NTT Software Corporation.
テストコードが緑に
なっている
Copyright © 2016, NTT Software Corporation. 39
JUnit4とAndroid Testing Support Library
JUnit4 (1/3)
Javaで広く使われているテストフレームワーク
http://junit.org/
40
public class MyJUnit4Test {
@Before
public void setUp() { /* テスト開始前の処理 */ }
@Test
public void 何かのテストをする() { /* テスト本体 */ }
@After
public void tearDown() { /* テスト終了後の処理 */ }
}
Copyright © 2016, NTT Software Corporation.
JUnit4 (2/3)
テスト結果が期待通りかどうかは
assertThat(actual, expected)
を使う
41
// この2つをstatic importしておく
import static org.hamcrest.CoreMatchers.*;
import static org.junit.Assert.assertThat;
...
// 使用例
assertThat(x, is(3));
assertThat(x, is(not(4)));
assertThat(myList, hasItem("3"));
※ 参考: マイナビニュース
『速攻解説! JUnit 4.4 - 新アサーションメソッド「assertThat」の用途とは』
http://news.mynavi.jp/articles/2007/07/20/junit1/
Copyright © 2016, NTT Software Corporation.
JUnit4 (3/3)
(参考)JUnit3との違い
Copyright © 2016, NTT Software Corporation. 42
JUnit3 JUnit4
テストクラス TestCaseクラスを継承 特に制限なし
テストメソッ
ド
「test」から始まる
メソッド
「@Test」が付いているメソッド
前処理 「setUp()」を
オーバーライド
「@Before」が付いているメソッド
後処理 「tearDown()」を
オーバーライド
「@After」が付いているメソッド
検証 assertEquals(expected,
actual)
assertThat(actual, expected)
ATSL (Android Testing Support Library)
Instrumented Testで事実上必須のライブラリ
'com.android.support.test:<ライブラリ名>:<バージョン>'
Copyright © 2016, NTT Software Corporation. 43
ライブラリ名 概要
runner 【必須】JUnit4が使えるようになる
rules 【必須】JUnit4でActivityにアクセスできるようになる
espresso:* Espressoが使えるようになる
uiautomator:* UI Automatorが使えるようになる
SDK Managerで以下をダウンロードしておく必要がある
Extras>Android Support Repository
Extras>Android Support Library
Copyright © 2016, NTT Software Corporation. 44
テスト対象アプリの紹介
テスト対象アプリの特徴
足し算をするシンプルなアプリケーション
テキストボックスの入力値を足し算した結果を表示
ダイアログによる表示
同一画面の「結果:」欄への表示
数字以外の入力時はエラーダイアログを表示
Copyright © 2016, NTT Software Corporation. 45
テスト対象アプリの画面遷移(1/3)
「ダイアログ表示」ボタンを押下した場合
「ダイアログ表示」
ボタンを押下する
AdditionViewActivity
Copyright © 2016, NTT Software Corporation. 46
テスト対象アプリの画面遷移(2/3)
「この画面に表示」ボタンを押下した場合
「この画面に表示」
ボタンを押下する
計算結果が
表示される
Copyright © 2016, NTT Software Corporation. 47
テスト対象アプリの画面遷移(3/3)
エラー時に表示するダイアログ
値1・値2のいずれかが数字以外の場合に表示
Copyright © 2016, NTT Software Corporation. 48
テスト対象アプリの内部仕様
入力内容を確認するバリデータ:
AdditionViewActivity#isValid(String, String): boolean
引数の両方がintに変換可能な場合: true
いずれかがintに変換できない場合や、nullの場合: false
Copyright © 2016, NTT Software Corporation. 49
ViewのリソースID
R.id.value1
R.id.value2
R.id.result_value
R.id.page_buttonR.id.dialog_button
Copyright © 2016, NTT Software Corporation. 50
【演習1-1】
単純なInstrumented Test
 演習課題
 ATSLのための設定
51Copyright © 2016, NTT Software Corporation.
演習課題
以下の作業を通じて、単純なInstrumented Test
を完成させてください
Android Studioで
演習用プロジェクト「system-test-exercise」を開く
ATSLを使うように、build.gradleを修正する
以下のテストケースを作成する
テスト対象:
AdditionViewActivity#isValid(String, String)
テスト内容:
引数に"5", "8"を指定して呼び出した場合にtrueが返ること
テストクラス名: SimpleInstrumentationTest
テストメソッド名: isValid_normal()
Copyright © 2016, NTT Software Corporation. 52
ATSLのための設定: build.gradle
app/build.gradle
Copyright © 2016, NTT Software Corporation. 53
android {
defaultConfig {
...
testInstrumentationRunner ¥
'android.support.test.runner.AndroidJUnitRunner'
}
}
dependencies {
androidTestCompile ¥
'com.android.support.test:runner:0.5'
androidTestCompile ¥
'com.android.support.test:rules:0.5'
}
ATSLのための設定: テストクラス
テストクラス(app/src/androidTest/java/配下)
Copyright © 2016, NTT Software Corporation. 54
@RunWith(AndroidJUnit4.class)
public class SimpleInstrumentationTest {
@Rule
public ActivityTestRule<AdditionViewActivity> activityTestRule
= new ActivityTestRule<>( AdditionViewActivity.class );
private AdditionViewActivity activity;
@Before
public void setUp() throws Exception {
activity = activityTestRule.getActivity();
}
@Test public void isValid_normal() { ... }
}
日本語名のテストメソッドだと
メソッド指定のテスト実行不可
テスト対象Activity
https://www.ntts.co.jp/products/soft_dojyo/index.html

Androidテスティング実践 基礎編