実践android developer testing
DESCRIPTION
TRANSCRIPT
Developers Summit 2012
実践 Android Developer Testing
12年2月17日金曜日
Developers Summit 2012
本日のアジェンダと登壇者 テスト部の取り組みとテストレベル/自動化について松木 晋祐 @snsk Androidテスト部副部長 / NPO法人 ASTER 関連活動アジャイルプロセス協議会 テスト・レビューWG / ツールの活用を考える会他株式会社ACCESS 名刺に書いてないけど赤魔道士
テスト自動化ツールの紹介長谷川 孝二 @nowsprinting フリーランスの開発者。メインジョブはプログラマー、サブでテストとかサムライ(居合)とか。なかなかレベル上がらないのが悩み。
12年2月17日金曜日
Developers Summit 2012
本日のアジェンダと登壇者 Model分離を用いたテスタビリティの向上持田 真哉 @mike_neck Android テスト部部員。株式会社トップゲート所属のプログラマー。Java、
Javascript、Groovyをやっています。以前所属していたSIerでの単体テストのあり方に疑問を持ち、テストの勉強を始めた。
ユニットテストの掘り下げ、SQLiteまわり吉澤 毅 @ussy00 Android テスト部部員。テスト部がシーンに放つ部屈指のメガネ男子。彼が部で披露するテクノロジーのプレフィックスには「オシャレ~」が付く鉄の掟がある。株式会社ヌーラボ ジョブはプログラマー
まとめと質疑応答全員
12年2月17日金曜日
Developers Summit 2012
Androidアプリのテスト全般について 情報共有 情報発信
オープンプロダクトコミュニティにおける「ぶっちぎりのテスト力」をテスト部から世界へ
Androidテスト部(ATEC)ご紹介
12年2月17日金曜日
Developers Summit 2012
主な活動
(だいたい)月1回のMTGで情報共有 Androidテスト祭り開催 ABCで講演/JaSST LT殴りこみ @IT連載「Androidアプリ開発入門」 メンバーが400人を超えました!
2012/2頭 時点で423名
12年2月17日金曜日
Developers Summit 2012
最近の活動 ソースかつチーム
主に低層のテスト技術を調査 Androidアプリの開発者がテストしやすいように Androidアプリの品質を向上 翻訳・SDKのコードリーディング
ハッピーターンチーム 主に上層のテスト技術を調査 品質保証の観点からAndroidテストを考える Androidアプリの受入れガイドライン作成
Testterを主軸に検証 https://sites.google.com/site/
androidtestclub/testter
12年2月17日金曜日
Developers Summit 2012
最近のホットなニュース
テスト部に予算がつきました! Sponsored by
@IT連載開始
CIサーバ調達しました!
12年2月17日金曜日
Developers Summit 2012
その他もろもろ
• メンバー紹介o https://sites.google.com/site/
androidtestclub/members• テスト対象のアプリ→Testter
o https://sites.google.com/site/androidtestclub/testter
• 名刺o https://sites.google.com/site/
androidtestclub/business-card12年2月17日金曜日
Developers Summit 2012
本編
12年2月17日金曜日
Developers Summit 2012
テストの段階「テストレベル」
テストレベル:組織的に管理されるテスト作業のグループ。テストレベルはプロジェクトの責任に対応するソフトウェアテスト標準用語集 v2.0.J01 より
12年2月17日金曜日
Developers Summit 2012
受け入れテスト
システムテスト
結合テスト
単体テスト
通称:デベロッパーテスティング
通称:?
今日のお話は主にここ
テストの段階「テストレベル」
12年2月17日金曜日
Developers Summit 2012
テスト自動化の3要素或いはテスト自動化とは何か?
Drive JUDGE Report
上記3要素のすべてを何らかの形で満たす必要がある。現在の主要なツールはほぼ全て満たしているが、どの部分がどの機能で満たされているのかを導入時に認識しておく
12年2月17日金曜日
Developers Summit 2012
テスト自動化ツールの紹介
12年2月17日金曜日
Developers Summit 2012
早速ですが、デモ
Robotium 主にView(GUIコンポーネント)を指定して操作
monkeyrunner 座標指定でタップ、ドラッグ
12年2月17日金曜日
Developers Summit 2012
今すぐ使える!11のツール/フレームワーク
12年2月17日金曜日
Developers Summit 2012
View操作系(1/3)
ActivityInstrumentationTestCase2 Android SDK内 android.testパッケージ。JUnit3
座標指定タップ、ドラッグも可能
Robotium ↑の拡張。Activity間の遷移を伴なうテストが可能
scirocco ↑の拡張。スクリーンショット、レポーティング
12年2月17日金曜日
Developers Summit 2012
View操作系(2/3)
NativeDriver By Google. 2011/6リリース。ASL 2.0
テストコードはJUnitで記述
端末の回転、向きの取得、スクリーンショット
apkにserver-standalone.jarの埋め込み&起動が必要
WebDriver, NativeDriver for iOS
12年2月17日金曜日
Developers Summit 2012
View操作系(3/3)
FoneMonkey By Gorilla Logic. 2011/11リリース。GPL v3
専用スクリプトを表形式のGUIで編集
実機でのrecording/playback
JUnitのコードにexport可能(独自TestRunner)
FlaxMonkey, FoneMonkey for iOS
12年2月17日金曜日
Developers Summit 2012
座標指定系
monkeyrunner Android SDK同梱 テストコードはPythonで記述
スクリーンショット、画像比較による判定
ソースの中にmonkeyrecorder/playback.py
座標計算などのユーティリティをテスト部で作成
12年2月17日金曜日
Developers Summit 2012
特殊なもの
Monkey Android SDK同梱 モンキーテスト(ランダムに操作)
SIKULI スクリーンショットからテストを書くタイプ PC向けだが、Androidエミュレータで利用可能
12年2月17日金曜日
Developers Summit 2012
ユニットテスト向け
Android Testing Framework AndroidTestCase、ActivityUnitTestCaseなど @IT連載の第2回・第3回で紹介
AndroidMock EastMockのAndroid向けラッパー @IT連載の第5回(3月公開)で紹介予定
Robolectric JavaVM上でAndroidのテストを実行するもの
12年2月17日金曜日
Developers Summit 2012
上層(GUI)テスト自動化の導入判断について
12年2月17日金曜日
Developers Summit 2012
テスト自動化が有利
実行機会が多い 複数機種、複数Androidバージョン アプリの頻繁なバージョンアップ
特殊なテスト 並列処理テスト(連続タップ、同時タップ) 負荷テスト
12年2月17日金曜日
Developers Summit 2012
テスト自動化が不利
自動テストの記述にコストがかかる Judgeまで自動化するのは難しい サーバとの通信、データベース
UIの変更が多く再利用できない 開発終盤や機能追加のたびにUIが変わる ActionBar対応を…強いられているんだ!
12年2月17日金曜日
Developers Summit 2012
ここまでのまとめ
上層のテスト自動化は無理なく、 計画的に
下層のテストをより厚く この後、ノウハウを紹介します!
12年2月17日金曜日
Developers Summit 2012
ユニットテストの導入
12年2月17日金曜日
Developers Summit 2012
Androidアプリケーションのユニットテスト
• Activityだけでできているレガシーコードのアプリケーションにテストを付与する手順を説明します。
• なお、ここでレガシーコードというのは「テストのないコード」(マイケル・C・フェザーズ『レガシーコード改善ガイド』翔泳社)を指します。
12年2月17日金曜日
Developers Summit 2012
AndroidのActivityのコード
onCreate(Bundle bundle) { // レイアウトのレンダリング // メッセージの処理 // データ処理 // ビューの表示(操作) // リスナーの割り当て}
12年2月17日金曜日
Developers Summit 2012
AndroidのActivityのコード
onCreate(Bundle bundle) { // レイアウトのレンダリング // メッセージの処理 → C // データ処理 → M // ビューの表示(操作) → V // リスナーの割り当て → V / C}
12年2月17日金曜日
Developers Summit 2012
AndroidのOnClickListenerのコード
onClick(View view) { // メッセージ取得 // データ処理 // ビューの表示(操作) // メッセージの送信}
12年2月17日金曜日
Developers Summit 2012
AndroidのOnClickListenerのコード
onClick(View view) { // メッセージ取得 → C // データ処理 → M // ビューの表示(操作) → V // メッセージの送信 → V / C}
12年2月17日金曜日
Developers Summit 2012
モデルが分離できていないActivityのコード例
Viewに関するコード
Modelのコード
Modelのコード
12年2月17日金曜日
Developers Summit 2012
モデルが分離できていないActivityのコード例
http://goo.gl/YiH1w
12年2月17日金曜日
Developers Summit 2012
Model - アプリケーションの核
• ロジック処理o データの規則を記述o データの整形
• データ永続化層へのアクセスo データの保存o データの取得
12年2月17日金曜日
Developers Summit 2012
Androidアプリケーション時代の永続化層
• Database (SQLite3)• ネットワーク (SNSなど)• 各種センサー
o 加速度センサーo 温度センサーo GPS
12年2月17日金曜日
Developers Summit 2012
アプローチ
• Activityに対するテストを記述してActivityを保護する
• テストの保護の上にモデルをActivityから分離して、モデルに対するテストを記述する
12年2月17日金曜日
Developers Summit 2012
実際にテストを記述していく
• Modelの状態をViewによって確認する• ModelとViewが混在しているテスト• 不具合が確認された場合、ModelとViewの双方を確認していくことになる
12年2月17日金曜日
Developers Summit 2012 12年2月17日金曜日
Developers Summit 2012
初回実行時は成功する
12年2月17日金曜日
Developers Summit 2012
二回目に実行すると失敗する
12年2月17日金曜日
Developers Summit 2012
原因と対策
• 原因o データベースの状態に依存するテストになっている
• 対策o ActivityInsterumentationTestCase2<T
extends Activity>のsetUpメソッドにてデータベースを初期化する
12年2月17日金曜日
Developers Summit 2012 12年2月17日金曜日
Developers Summit 2012
再度実行してみるが落ちる
12年2月17日金曜日
Developers Summit 2012
原因を探る• ActivityInstrumentationTestCase2<T extends
Activity>のgetActivityメソッドにてActivity onCreateとonResumeまで実行される。
• 起動後のActivityを元にDatabaseを取得して初期化する
• 起動後のActivityの状態からViewを取得して値を確認する
12年2月17日金曜日
Developers Summit 2012
原因を探る• ActivityInstrumentationTestCase2<T extends
Activity>のgetActivityメソッドにてActivity onCreateとonResumeまで実行される。
• 起動後のActivityを元にDatabaseを取得して初期化する
• 起動後のActivityの状態からViewを取得して値を確認する
→異なるものを比較している!
12年2月17日金曜日
Developers Summit 2012
回避方法
テスト内でもう一度onCreateメソッドを呼び出す
12年2月17日金曜日
Developers Summit 2012
Threadが違うことに注意が必要
12年2月17日金曜日
Developers Summit 2012
Activityと同じThread上でonCreateを呼び出すことで回避
12年2月17日金曜日
Developers Summit 2012
Activityのテストによる保護が完成する
後はActivityのテストを落とさないようにModelに該当する部分を外部化していく
12年2月17日金曜日
Developers Summit 2012
Modelを外部化した後のActivityのコード
12年2月17日金曜日
Developers Summit 2012 12年2月17日金曜日
Developers Summit 2012
Viewに関するコードModelのコード
12年2月17日金曜日
Developers Summit 2012
ActivityInstrumentationTestCase2<T extends Activity>
• データから想定されるViewの結果を検証• ModelとViewが混在しているため、これはUnit Testとは言えない
• Modelに関するテストを行いたいが、ThreadやActivityライフサイクルに注意しなければならない
12年2月17日金曜日
Developers Summit 2012
ActivityInstrumentationTestCase2<T extends Activity>
• データから想定されるViewの結果を検証• ModelとViewが混在しているため、これはUnit Testとは言えない
• Modelに関するテストを行いたいが、ThreadやActivityライフサイクルに注意しなければならない
12年2月17日金曜日
Developers Summit 2012
テストをしていくにあたって
• Modelのテストを実施していくにあたって、ThreadやActivityライフサイクルに注意をはらうのはコストが高い
• コストの高いテストは実施されなくなるo テストのコスト×テスト実施頻度=一定値(テキトーな式です)
12年2月17日金曜日
Developers Summit 2012
Androidアプリケーションにテストを挟み込むコツ
Activityからモデルを分離する!
12年2月17日金曜日
Developers Summit 2012
ユニットテストの掘り下げSQLite まわり
12年2月17日金曜日
Developers Summit 2012
テストデータの投入
@Overrideprotected void setUp() throws Exception { super.setUp();
helper = new AllowanceDatabase(new RenamingDelegatingContext(getContext(), "test_"));
SQLiteDatabase db = helper.getWritableDatabase(); try { db.execSQL("INSERT INTO ALLOWANCE_LOG(LOG_DATE, AMOUNT) VALUES(1320000000, 1000);"); db.execSQL("INSERT INTO ALLOWANCE_LOG(LOG_DATE, AMOUNT) VALUES(1330000000, 5000);"); db.execSQL("INSERT INTO ALLOWANCE_LOG(LOG_DATE, AMOUNT) VALUES(1340000000, 10000);"); db.execSQL("INSERT INTO ALLOWANCE_LOG(LOG_DATE, AMOUNT) VALUES(1350000000, 2000);"); db.execSQL("INSERT INTO ALLOWANCE_LOG(LOG_DATE, AMOUNT) VALUES(1360000000, 3000);"); } finally { db.close(); }}
SQL 文を記述
12年2月17日金曜日
Developers Summit 2012
Fixture Library
テストデータセットアップ自動化 DBUnit (Java) ActiveRecord (Ruby) Test::Fixture::DBI (Perl) fixture (Python) Factory Girl (Ruby) ???? (Android)
12年2月17日金曜日
Developers Summit 2012
Fixture for Android
SQLite Fixture Library https://github.com/ussy/sqlite-fixture
テストデータをファイルから投入 テスト専用 DB を作成 RenamingDelegatingContext
12年2月17日金曜日
Developers Summit 2012
テストデータ
@Overrideprotected void setUp() throws Exception { super.setUp();
importData(FileType.Yaml, "AllowanceLogDataTest");}
テストデータ格納ディレクトリを指定
12年2月17日金曜日
Developers Summit 2012
テストデータ---_id: 1LOG_DATE: 1320000000AMOUNT: 1000---_id: 2LOG_DATE: 1330000000AMOUNT: 5000---_id: 3LOG_DATE: 1340000000AMOUNT: 10000---_id: 4LOG_DATE: 1350000000AMOUNT: 2000---_id: 5LOG_DATE: 1360000000AMOUNT: 3000
12年2月17日金曜日
Developers Summit 2012
Fixture Library まとめ
テスト専用データベースの自動 テストコードをみやすく 工夫することでテストを楽にできる
12年2月17日金曜日
Developers Summit 2012
テストプロジェクトの罠
公開 API から、テストプロジェクトへのリソースへアクセスできない
リフレクションで取得している
12年2月17日金曜日
Developers Summit 2012
マイグレーション
12年2月17日金曜日
Developers Summit 2012
マイグレーション問題
確認作業が面倒 バージョンアップ作業を実機で確認?
クライアントならではの問題
12年2月17日金曜日
Developers Summit 2012
DB 移行バージョン問題
12年2月17日金曜日
Developers Summit 2012
解決案 各バージョンごとに SQLiteOpenHelper クラスを用意
https://github.com/ussy/android-dbtest
12年2月17日金曜日
Developers Summit 2012
マイグレーションテストコードprivate Context context;
protected void setUp() { context = new RenamingDelegatingContext(getContext(), "test_");
helper = new SQLiteOpenHelperV1(context);}
public void testMigration() { helper = SQLiteOpenHelperFactory.get(context); // test code}
12年2月17日金曜日
Developers Summit 2012
テストの自動化
12年2月17日金曜日
Developers Summit 2012
CI
継続的インテグレーション ビルド、テスト、成果物生成を継続的に実行する
12年2月17日金曜日
Developers Summit 2012
Jenkins
12年2月17日金曜日
Developers Summit 2012
Android Emulator Plugin
自動ビルド、自動テスト エラー通知 APK ファイル生成 Android フラグメンテーション問題
解像度 OS バージョン
12年2月17日金曜日
Developers Summit 2012
まとめ
12年2月17日金曜日
Developers Summit 2012
デベロッパーテスティング心得
テストを楽にしていきましょう 不安なところを重点的にテストして、不安を取り除きましょう
Jenkins を導入して、自動化しましょう パッケージもつくらせて楽をしましょう
12年2月17日金曜日
Developers Summit 2012
テスト自動化の3世代
Level1 Automation Record&Playback
Liner Script
Level2 Automation Data-driven Functional Decomposition
Level3 Automation Keyword Driven Model-based
TEST AUTOMATIONBODY OF KNOWLEDGE(TABOK) GUIDEBOOK Version 1.1
12年2月17日金曜日
Developers Summit 2012
テスト自動化の3原則
受け入れテスト
システムテスト
結合テスト
単体テスト
1.上層にいくほどテスト自動化のコストと技術的ハードルが上がる
2.上層のテストはスコープが広いが欠陥までの距離が遠い。下層はその逆。
3.上層のテストは見た目の変化に弱い*1
下層のテストは「どう動くか」を保証しにくい
*1 と言われていたが第3世代の自動化ではこれを克服しつつある
12年2月17日金曜日
Developers Summit 2012
ご清聴ありがとうございました。
12年2月17日金曜日