スキップしてメイン コンテンツに移動

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

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が呼ばれるのを待機する必要がある点です。

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

参考

コメント

このブログの人気の投稿

GolangでWindows GUIアプリケーション

GUIアプリ作成の前提 社内ツールとしてexeで配布 開発環境はGoLandを使う 社内ツールとしてexeを配布ということであれば、Visual StudioでC#による開発だと思います。しかしながら、Go言語を習得したいのと、GoLandの補完機能が便利で、Android Studio使っていたこともあり、とっつきやすいという点からGo縛りでGUIアプリケーションを考えたいと思います。 lxn/walk Windows application library kit for Go. Windows向けしか考えていないので、まずこのライブラリなのですが、ボタンやコンボボックスが思ったように並ばなかったり、手軽にイメージボタンを配置したりなど、簡単にレイアウトを変更できない課題に直面しました。レイアウト作成だけで時間を取られてしまいます。そう言えば、Androidアプリ開発のときは、XMLでデザイン部分を切り離してたのを思い出して、今回の調査の運びとなりました。 fyne-io/fyne Cross platform native GUIs designed for Go based on Material Design. Supports: Linux, macOS, Windows, BSD, iOS and Android. walkと比べると、クロスプラットフォームで作成できるのですが、こちらもコードの中にデザインを書いていく形でした。 therecipe/qt therecipe/qt allows you to write Qt applications entirely in Go or JavaScript. Qt Creatorなるものがあるようで、デザイン部分を切り離せる印象はあるものの、最新のPCでもビルドに時間がかかるようで、学習コストもかかるという記事を見かけて断念しました。 どうしたものかとツイートしましたら、下記のようにご助言をいただいた。 同じ課題に対し色々試した結果、PWAのフルキャッシュドに落ち着いた。中身はGo+WASMで。 https://t.co/e60whDTV16 — のぼのぼ📡 (@nobonobo) July 21, 2020 PWA 早速調べてみました。Googleが進めているプロジェクトで、ネイティブアプリのよ

Javaでprivateなfieldやmethodにアクセスする

JUnitでテストしてると、privateなフィールドにアクセスして、値を参照したりセットしたりしたくなるわけですが、よく使うのでメモしておきます。 例えば、次のような対象のクラスがあるとします。 public class ParentClass { private String hoge = "ParentClass!!"; public void dispMsg() { System.out.println("dispMsg:" + hoge); } private void privateDispMsg(String msg) { System.out.println("dispMsg:" + msg); } }

Eclipseで一通り基本的なGitを使ってみる

備忘録的にまとめておきたいと思います。おかしな点があればご指摘いただければ幸いです。 目次 環境 プロジェクト作成~初コミットまで コミットの履歴&差分を見る 元に戻す ブランチについて ブランチを作成してみる ブランチを統合するには マージする Rebaseする ローカルリポジトリからプロジェクトを取り込む コミットしたメッセージの修正 環境 Eclipse IDE for Java Developers:Juno Service Release 1 Git:上記Eclipseのプリインストール版