Androidアプリの作成に当たって、プログラムがイメージ通り動くか、作成したアプリにバグが隠れていないか、といった心配はありませんか。このような隠れたバグ(不具合)を洗い出す作業にはテストが有効です。プログラムが正しく動いていることを確認するだけなら手作業で確認しても良いのですが、テストコードを作成すれば自動で何度でも繰り返しテストが実行できるという利点があります。
一般的にJavaプログラムをテストするには、JUnitなどのテストフレームワークを用いてテストを行います。最も基本的なテストがUnitTest(単体テスト)と呼ばれるものです。UnitTestとは、クラスやメソッドなどの単位でテストする手法です。
ところが一般的なJavaプログラムと違って、AndroidアプリでのUnitTestは少し面倒です。テストフレームワークは、旧バージョンのJUnit 3を使わなければなりませんし、テストを実行しても待ち時間が長く、ストレスがたまります。また、UnitTestを実行する際には、通常のアプリケーションとテスト用のアプリの二つをインストールして、テストが終わるまで待たなくてはなりません。比較的高速に開発のサイクルを回せる実機でテストできれば良いのですが、エミュレータなどを使っていると、その苦痛は何倍にもなります。
ただ気持ち良く開発したいだけなのに、なぜこんな面倒なのだろうと考えたことはありませんか? 「Robolectric」は、そんな不満を解消してくれるテスト用のライブラリです。Robolectricを使ってテストを記述すると、実機やエミュレータを利用することなく、PC上でUnitTestが実行できるのです。
Robolectricとは?
Robolectricは、UnitTestを端末レス・エミュレータレスで可能にするライブラリです。初回実行時にクラスを動的に生成するため少し時間がかかりますが、2回目以降はテストの開始と実行・終了までに、短ければ1秒で全行程が終了するという夢の様なライブラリです。ただし、構成管理ツールであるApache Mavenの利用がほぼ必須のため、若干ハードルが高いかもしれません*1。
Robolectricが動く仕組みを説明しましょう(図1)。エミュレータを使わなければ、Android特有のクラスであるActivityなどはPC上で動きません。一方、Robolectricでは、Androidのクラスに対してShadowActivity(Shadowクラス)というクラスを事前に用意しておきます。実行時には、Activityに見せかけたShadowActivityを動作させることでPC上でのテストを実現しています。
この動作の裏側では、Javassistと呼ばれるJavaのバイトコード変換ライブラリを利用します。実行時にAndroidのActivityに対して、事前に用意しておいたShadowActivityクラスに処理を移譲し、実際に動く際にはActivityの代わりにShadowActivityのコードが実行されるという仕組みです。Shadowクラスが存在しない場合や、存在していても実装されていないメソッドについては、Robolectricを使ってもうまくテストできません。
よく利用される有名なクラスは、対応するShadowクラスが既に用意されています。しかし、Shadowにないクラスもあります。その際は、自分でShadowクラスを作成しなければなりません。
筆者も、ShadowSQLiteDatabaseクラスに、beginTransactionやsetTransactionSuccessful、endTransactionといったメソッドがなかったため、実装して取り込んでもらったことがあります。GitHubのRobolectricのリポジトリを見ると、多数の開発者が頻繁にShadowクラスを追加して、取り込んでもらえるようにリクエストを送っていることがわかるでしょう。