AndroidのInstrumented Unit Testsを試す
試したのはAndroidの公式の以下のページの内容になります。
Building Instrumented Unit Tests | Android Developers
準備
基本的には手順通りにやれば問題なく出来ます。
- Android Testing Support Libraryをインストール
- 画面左下のBuild Variantsタブを選択し、Test ArtifactをAndroid Instrumentation Testsに変更しておく
- app/src/androidTest/javaディレクトリを作成
- moduleのbuild.gradleにdependenciesを追記
- 僕の環境だとhamcrestが入っているとダメでした *1
dependencies { androidTestCompile 'com.android.support.test:runner:0.3' androidTestCompile 'com.android.support.test:rules:0.3' // Set this dependency if you want to use Hamcrest matching androidTestCompile 'org.hamcrest:hamcrest-library:1.1' }
- 同じくmoduleのbuild.gradle内のtestInstrumentationRunnerをAndroidJUnitRunnerに設定する
android { defaultConfig { testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" } }
実装
テストクラスは以下のように実装します。
Contextは InstrumentationRegistry
から取得出来るようです。
package com.example; import android.content.Context; import android.support.test.InstrumentationRegistry; import android.support.test.runner.AndroidJUnit4; import junit.framework.Assert; import org.junit.Test; import org.junit.runner.RunWith; @RunWith(AndroidJUnit4.class) public class SampleTest { @Test public void testSample() { // Contextの取得 Context c = InstrumentationRegistry.getContext(); Assert.assertEquals(2, 1 + 1); } }
1つ注意したいのはAndroidJUnit4を使用する時はWorkerThreadで動作するようで、Looper.myLooper()がnullになっているので new Handler()
等のコードを通ると内部で以下のエラーが起きます。
Caused by: java.lang.RuntimeException: Can't create handler inside thread that has not called Looper.prepare() at android.os.Handler.<init>(Handler.java:200) at android.os.Handler.<init>(Handler.java:114)
WebViewなんかも初期化時にHandlerを生成するらしく、普通に生成しようとすると同様のエラーが出て生成出来ません。
対策としては、Handlerを使ってMainThreadで動作するようにしてあげればOKです。
Handler handler = new Handler(Looper.getMainLooper()); handler.post(new Runnable() { @Override public void run() { // ここにテストコードを書く } });
追記
InstrumentationクラスのrunOnMainSyncメソッドを使えば同じようなことが出来るみたいです。こちらだと同期で実行してくれるのでこのRunnableが終わるまで待ってくれるのでテストを書くならこちらの方がやりやすいかもしれません。
InstrumentationRegistry.getInstrumentation().runOnMainSync(new Runnable() { @Override public void run() { // ここにテストコードを書く } });
実行
実行はJUnitなどを実行する時と同様にテストしたい対象を右クリックしてAndroid TestのRun (ドロイド君のマークのRun) を実行します。
GenyMotionを使用している場合は、初期状態だとデバイスを立ち上げていても勝手にAndroidのエミュレータが立ち上がるようになっていると思うので *2 、Run > Edit Configurations からTarget Deviceを Show chooser dialog に設定しておくと良いと思います。
テスト結果はJUnitのLocal Testingと同様にRunタブに表示されます。