!!!Android Activity の テスト [Android] *http://developer.android.com/guide/topics/testing/activity_testing.html !!!概要 *Activity のテストはかなり Android instrumentation framework に依存する *Activity は他のコンポーネントとは異なり、コールバックメソッドに基づいた、複雑なライフサイクルを持っているため *これらは、instrumentation 以外から直接呼び出すことができない *プログラムからイベントをユーザーインターフェースへ送る唯一の方法は、instrumentation を通して !!!Activity テスト API *Activity テスト API の基底クラスは、[InstrumentationTestCase|http://developer.android.com/reference/android/test/InstrumentationTestCase.html] *テストケース派生クラスへActivityのための操作方法を提供する !![InstrumentationTestCase|http://developer.android.com/reference/android/test/InstrumentationTestCase.html]が提供する機能 !ライフサイクル制御 *テストケースクラスが提供するメソッドから、Activity を開始でき、一時停止でき、破棄できる !依存性の注入 *Instrumentaion は、Contexts や Application のようなシステムオブジェクトのモックを作成することができ、テストで利用できる *れこは、テスト環境の制御を助け、製品のシステムから隔離する。 *カスタムインテントを用意し、それによりActivityを開始することもできる !ユーザーインターフェースインタラクション *Instrumentaion を キーストロークおよびタッチイベントを直接 Activity のユーザーインターフェースに送るために利用できる !!JUnit Activity テストクラスは、TextCase と Assert クラスを継承した、JUnit フレームワークも提供している !!2つの主のテスト用サブクラス * [ActivityInstrumentationTestCase2 |http://developer.android.com/reference/android/test/ActivityInstrumentationTestCase2.html] および、[ActivityUnitTestCase|http://developer.android.com/reference/android/test/ActivityUnitTestCase.html] *Activity を通常ではないモードで起動した場合には、[SingleLaunchActivityTestCase|http://developer.android.com/reference/android/test/SingleLaunchActivityTestCase.html] を利用する !!![ActivityInstrumentationTestCase2|http://developer.android.com/reference/android/test/ActivityInstrumentationTestCase2.html] *[ActivityInstrumentationTestCase2|http://developer.android.com/reference/android/test/ActivityInstrumentationTestCase2.html] は、アプリケーションの一つ以上のActivity の機能を通常のシステム基盤を用いて、テストするためにデザインされている *通常のシステムコンテキストを利用してアプリケーションの通常のインスタンスでActivityを起動する。 *モックのインテントをActivityに送信することができるので、 *複数のタイプのインテントに対する応答をテストできる *インテントに含まれるデータタイプの確かさを期待するActivity をテストできる ""製品のシステムの残りの部分からテストが隔離されていないため、モックのContext および Application は利用できない !!![ActivityUnitTestCase|http://developer.android.com/reference/android/test/ActivityUnitTestCase.html] *[ActivityUnitTestCase|http://developer.android.com/reference/android/test/ActivityUnitTestCase.html] は、隔離された、ただ一つのAcitivity をテストする。 *Activity を開始する前に、モックのContext または Application (もしくは両方) を注入することができる *そして、Androidと影響し合うことなしに、メソッドのユニットテストを行うことができる *テスト時にモックのインテントを Activity に送ることはできない *しかしながら、[Activity.startActivity(Intent)|http://developer.android.com/reference/android/app/Activity.html#startActivity(android.content.Intent)] を呼び出すことはできるし、受け取った引数を確認することが可能 !!!SingleLaunchActivityTestCase *[SingleLaunchActivityTestCase|http://developer.android.com/reference/android/test/SingleLaunchActivityTestCase.html] は、複数のテストの間、変化しない環境の中のただ一つのAcitvityをテストするのに便利なクラス *[setUp()|http://developer.android.com/reference/junit/framework/TestCase.html#setUp()] と [tearDown()|http://developer.android.com/reference/junit/framework/TestCase.html#tearDown()] をメソッドの呼び出ごとに呼び出す代わりに、たった一度だけ呼び出す。 *いかなるモックオブジェクトの注入も許可しない !!!モックオブジェクトとActivityのテスト *[android.test.mock|http://developer.android.com/reference/android/test/mock/package-summary.html] で定義される モックオブジェクトをAcitivity のテストに利用する !![MockApplication|http://developer.android.com/reference/android/test/mock/MockApplication.html] *[MockApplication|http://developer.android.com/reference/android/test/mock/MockApplication.html]は、 [ActivityUnitTestCase|http://developer.android.com/reference/android/test/ActivityUnitTestCase.html] を使う場合、Activity のテストに唯一有効。 *デフォルトでは、ActivityUnitTestCase は隠された MockApplication オブジェクトを生成しテストで使用する *独自のオブジェクトを、[setApplication|http://developer.android.com/reference/android/test/ActivityUnitTestCase.html#setApplication(android.app.Application)]で利用できる !!!Activityテストでのアサーション *[ViewAsserts|http://developer.android.com/reference/android/test/ViewAsserts.html] はViewのためのアサーションを定義する *Viewnoアライメントや位置、ViewGroup のステートを確認するのに利用できる !!!Eclipse ADT でのテスト *http://developer.android.com/guide/developing/testing/testing_eclipse.html !!テストプロジェクトの作成 *テスト環境を Ancroid アプリケーションにセットアップするには、最初にテストコードを含む分離されたプロジェクトを作成する必要がある *新しいプロジェクトは、Android アプリケーションのディレクトリ構造に従う *同じタイプのコンテンツとファイル、ソースコード、リソース、マニフェストファイルなどなどを含む *作成したテストパッケージはテスト時にマニフェストファイルの 要素に従ってアプリケーションに接続する *新規 Android テストプロジェクトダイアログは、それらを簡単に作成するし、いつでもできる *ダイアログは、新しい Android アプリケーション作成直後に表示されるが、事前に作成しておくこともできる !テストプロジェクトを作成するには ::File − New − Other *Android TestProject を選択し、Next {{ref_image android_test01.jpg}} ::Android Test Project ウィザード *Test Project Name:任意の名前がつけられるが、対象のプロジェクトに"Test"を付加するのが関連を表す一つの方法 *既存の Android プロジェクトを選択すると、必要な項目が自動で設定される {{ref_image android_test02.jpg}} !!テストパッケージの作成 *テストプロジェクトを作成したら、テストパッケージを作成する *パッケージは、Activity を必須とはしないが、望めば、定義することもできる *テストパッケージは、Activity、 テストケースクラスと通常のクラスと一体化可能ではあるが、メインとなるテストケースはAndroid テストケースクラスの一つ、もしくはJUnitクラスから継承すべきである。なぜなら、ベストなテスト機能を提供するから *テストパッケージは、Android GUI は必要としない *Eclipse ADT から起動する場合、JUnit ビューに結果が表示される *テストを実行し、結果を確認する詳細については、 [Running Tests|http://developer.android.com/guide/developing/testing/testing_eclipse.html#RunTestEclipse] を参照 *android.test にAndroid のテストケースクラスが定義されている *それらは、JUnit の [TestCase|http://developer.android.com/reference/junit/framework/TestCase.html] クラスを継承している !作成されたテストパッケージのコンテキストメニューから、New − Class *クラス名は、テストしたい対象のクラス名 + "Test" としておくのが一つの方法 *継承元は、上記で上げた基底クラスを指定する。(今回は、ActivityInstrumentationTestCase2) とした {{ref_image android_test03.jpg}} *クラスが作成されたら、ActivityInstrumentationTestCase2 の ジェネリック型に対象のActivity を指定する。 *テスト環境を制御するためには、setUp() と tearDown() メソッドをオーバーライドする ::setUp() *どのテストメソッドが呼ばれる前に呼ばれる *テスト用の環境をセットするのに使用する *ACTION_MAIN を伴った新しいインテントを生成するのに利用できる ::tearDown() *すべてのテストメソッドの後に呼び出される *ガベージコレクトおよびテスト用の設定のリセットに利用する ::例 package info.typea.shujiroid.free.test; import info.typea.shujiroid.core.ShujiView; import info.typea.shujiroid.free.R; import info.typea.shujiroid.free.ShujiActivity; import android.test.ActivityInstrumentationTestCase2; import android.test.TouchUtils; import android.view.Gravity; public class ShujiroidTest extends ActivityInstrumentationTestCase2 { private ShujiView shujiView; public ShujiroidTest() { super("info.typea.shujiroid.free", ShujiActivity.class); } @Override protected void setUp() throws Exception { super.setUp(); shujiView = (ShujiView) getActivity().findViewById(R.id.shujiview); } public void testDraw() { getActivity().runOnUiThread(new Runnable() { @Override public void run() { shujiView.requestFocus(); } }); TouchUtils.dragViewBy(this, shujiView, Gravity.CENTER, 500, 200); } } !ユーティリティ *[Assert|http://developer.android.com/reference/junit/framework/Assert.html] : JUnit のアサートクラス *[MoreAsserts|http://developer.android.com/reference/android/test/MoreAsserts.html] : Android の追加アサートクラス *[ViewAsserts|http://developer.android.com/reference/android/test/ViewAsserts.html] : View テスト用に便利なアサートクラス *[TouchUtils|http://developer.android.com/reference/android/test/TouchUtils.html]: タッチイベントシミュレーション用 !!テストの実行 *テストを Eclipse から実行するには、2つの方法がある **Run As ... − Android JUnit Test をプロジェクトのコンテキストメニューから選択 **Eclipse の run configuration を作成する {{ref_image android_test04.jpg}} *自動で、画面に描画された {{ref_image android_test05.png}}