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