Android、Java、Web系、Linux、マラソン等の備忘録

2015/09/22

Applicationを参照するActivity起動のテストをしたい。あるいは、Activityの結合テスト

0 件のコメント
Applicationとはandroid.app.Applicationのことで、これを継承したクラスをマニフェストに定義しておくと、Activity内でgetApplication()で取得できます。


Activity1でApplicationを継承したクラス内のフィールドに値をセットして、Activity2でその値を参照するといったことができます。Applicationはアプリが起動している間は保持されるので、いろいろ使えるわけですが、その値を利用して、Activity起動時に分岐するような処理を入れている場合のテストを考えます。


分岐だけをテストする場合

単純にActivityの起動時の分岐を単体テストしたい場合は、AndroidテストフレームワークのActivityUnitTestCaseを使うと良いと思います。setApplication()というメソッドがあるので、Instrumentation.newApplicationした自前のApplicationをセットできます。

コードなどはこちら→Mockitoを使ってActivityの分岐のテスト

ただし、あくまでもActitityのクラスを単体テストする目的のものなので、FragmentのViewの情報とかの値を参照できなかったりします。FragmentのViewを生成させる方法もあるかもしれませんが、たぶん大変かと思います。

アプリとしてActivityを起動させてテスト

Activityが起動して分岐した結果表示されたFragmentの情報などを検証を考えた場合、以下のメソッドでgetActivity()なりlaunchActivity()なりを実行すれば、Activityを起動できますが、
  • ActivityInstrumentationTestCase2
  • SingleLaunchActivityTestCase
  • InstrumentationTestCase
  • など
それら起動のメソッドを実行すと、onCreateなりonStartなり実行されてしまいます。起動時の処理のため、それらの前にApplicationを参照したいわけですが、getApplication()するにはActivityが必要というジレンマがあります。

Activityを介さずApplicationを取得する方法が(Androidのソースコードとか見ましたが)見つけられなかったので、以下のように工夫してみたいと思います。
  1. テストと関係ない適当なAcitityを起動させる。
  2. 1のActitityからgetApplication()してApplicationの値を書き換える
  3. 次にテスト対象のActivityを起動させる
  4. テスト対象のActivityを検証する
ちょっと強引ですが...こうするためには、テストケース内で1のActivityとテスト対象のActivityの両方のオブジェクトが必要です。それを実現させるためにこちらがとても参考になりました。
How do you test an Android application across multiple Activities? - Stack Overflow
http://stackoverflow.com/questions/1759626/how-do-you-test-an-android-application-across-multiple-activities
Applicationを参照するよう書き変えたのがこちら。※手元のコードを公開用に書き換えただけなので動作の確認はしてません。


これは、Activityの起動時の分岐のテストをしていますが、Stack Overflowにあるように呼び出し元のActivityと呼び出し先のActivityのオブジェクト両方が手に入るので、結合テストとしても使えますね。

Contextがあればどうにかなる場合

同じようにActivity起動時にデータベースの値を参照、または、SharedPreferencesに保存した値を判定して分岐するようなテストを行いたい場合は、ActivityInstrumentationTestCase2等でgetActivity()する前に、getInstrumentation().getContext()等でContextを取得できるので、このContextで書き換えることが可能です。

2015/09/24追記:onActivityResultをテストする場合

上記はActivity起動時の話ですが、Activityを2つ扱えることからonActivityResultのテストも行えます。以下の2つのActivityを扱う場合で、


TestTargetActivity内のonActivityResultをテストする場合を考えます。ポイントとなるのは、ChildActivityでfinish()を呼んだ後にTestTargetActivityでonActivityResultが呼ばれるのを待機する必要がある点です。

※手元のコードを公開用に書き換えただけなので動作の確認はしてません。

参考

0 件のコメント :

コメントを投稿