Androidアプリを作るのに、低スペックPCで エミュレーターを使ってテストしていると、遅いorz 重いorz もうやだ;;
となったので、テスト環境を考え直すことにした。
で、見つけたのが、これ、Robolectric
Robolectric
http://robolectric.org/
エミュレートせずに、Junitで片付けてしまおうぜ!というモノらしいw
まぁ、あの重いのを使わずに済むなら、と早速導入。
pomに依存関係を追加する、いつもの方法でMavenからの導入をすると、pom.xml がエラー。
簡単に解釈すると、[android-support-v4.jar]が依存関係にあるのだけれど、これを集めてくることが出来ないらしい。
しょうがないので、pomからの導入を諦めて、
The Central Repository Search Engine
http://search.maven.org/#search|ga|1|g%3A%22org.robolectric%22 から、jar-with-dependencies.jarを取ってくることにする。
このjarファイルだと、欲しいjarが全部入りなので、取りこぼしも無いし。
というわけで、ダウンロードしたjarをプロジェクトの参照ライブラリに追加して、テストを記述。
@RunWith(RobolectricTestRunner.class)
public class ClassRecordTest {
@Test
public void testToString() {
Record act = new Record();
assertThat(act, is(notNullValue()));
assertThat(act.toString(), is(notNullValue()));
}
}
Junit4のテストランナーで起動を確認!……できたのにorz
java.lang.UnsupportedOperationException: Robolectric does not support API level 19, sorry!
at org.robolectric.SdkConfig.<init>(SdkConfig.java:24)
at org.robolectric.RobolectricTestRunner.pickSdkVersion(RobolectricTestRunner.java:320)
at org.robolectric.RobolectricTestRunner.getEnvironment(RobolectricTestRunner.java:296)
at org.robolectric.RobolectricTestRunner.access$300(RobolectricTestRunner.java:61)
at org.robolectric.RobolectricTestRunner$2.evaluate(RobolectricTestRunner.java:202)
明るく「sorry!」とか言ってんじゃねぇっ!とツッコミしつつ、
@Config(emulateSdk = 18)
@RunWith(RobolectricTestRunner.class)
public class RecordTest {
@Test
public void testToString() {
Record act = new Record();
assertThat(act, is(notNullValue()));
assertThat(act.toString(), is(notNullValue()));
}
}
これで、なんとか動くようになった。本来のテストのコードはもっと色々と入ってるけど、ここでは割愛してまするw
さて、テストごりごり書いていこう。
テストプロジェクトの環境設定まとめ
もっとスマートな方法があるかもしれないけど、ベタな方法でw
使いたいJunitとツールは次のもの。
- Junit4
- Robolectric
- Mockito
- Dexmaker
Robolectricはpom.xmlから導入すると先述の問題が出ているので、それ以外をpom.xmlにセット。
<dependencies>
<dependency>
<groupId>com.j256.ormlite</groupId>
<artifactId>ormlite-android</artifactId>
<version>4.48</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.11</version>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.5</version>
</dependency>
<dependency>
<groupId>com.google.dexmaker</groupId>
<artifactId>dexmaker-mockito</artifactId>
<version>1.1</version>
</dependency>
</dependencies>
これを追加。バージョンについては、それぞれの最新を以下のサイトより。
Maven Repository: Search/Browse/Explore
http://mvnrepository.com/
そして、次の作業をして、テスト時に参照するクラスを一か所に集結。
- ダウンロードしてある、roborectricの with_all_dependencies.jar をプロジェクトの参照ライブラリにセット。
- テストで使用したいバージョンのAndroidライブラリ(ここでは18)を参照ライブラリにセット。
- その上で、プロジェクトのgen、src、testの出力先ビルドパスを/target/classesに統一。
これで、Junitを実行した時に、Junitに参照させたい全部のクラスが読み込める状態になる。これが出来てないと、Junitテストを実行すると No class not found で例外が起きちゃうので、気を付けておきたい設定だよね。
後は、テストを書いて、Junitテストの実行でOK。これならいつもの方法だから、早いし、低スペックPCでも安全。
たとえば、OrmLiteSqliteOpenHelperを継承して作ったヘルパークラスのテストを書いてみると、
/**
* Test for DatabaseHelper
* @author esten
*
*/
@SuppressLint("InlinedApi")
@Config(emulateSdk=18)
@RunWith(RobolectricTestRunner.class)
public class DatabaseHelperTest {
/**
* Test for onCreate
*/
@Test
public void testOnCreate() {
// get Context
Context context = Robolectric.application.getApplicationContext();
// assert Constructor
DatabaseHelper act = new DatabaseHelper(context);
assertThat(act, is(notNullValue()));
assertThat(act.getContext(), is(context));
// assert DAO class generate
RuntimeExceptionDao<DiceRecord, Long> actDao = act.getDiceRecordDao();
assertThat(actDao, is(notNullValue()));
// assert 4 Records in Database after initialize
long actRecCount = actDao.countOf();
assertThat(actRecCount, is(4L));
List<DiceRecord> actList = actDao.queryForAll();
assertThat(actList.size(), is(4));
}
}
これでJunit実行で確認OK。
テスティングペアも同プロジェクトにあるから、QuickJunitで行き来できるし、エミュも動かないから軽い。
これで引き続き、作業を進めようw