読者です 読者をやめる 読者になる 読者になる

ほげほげ(仮)

仮死状態

Android StudioからRobolectricのテストを直接実行する

Android

Android Studio + Robolectricでは基本的にターミナルからGradleで実行する感じっぽいですが、これだとテスト結果が見づらいし全部のテストを毎回実行するのはムダだと思うでAndroid Studioから直接テストを実行できるようにしました。

注意点としては結構面倒です。あと、まだ実際にガリガリとテストを書いてるわけではないのでなんか問題発生するかもしれません。

事前準備

前回書いた記事を参考にRobolectricをGradleから実行できるようにしておきます

AndroidStudio + Robolectric + Guardによる自動実行 - ほげほげ(仮)

Robolectric用の設定ファイルを用意する

<project path>/app/src/test/resources/org.robolectric.Config.properties のファイルを新規で作成します。

manifest=build/manifests/debug/AndroidManifest.xml
resourceDir=../../res/all/debug
emulateSdk=18

前回はアノテーション@Configで指定したのですが、全テストクラスで共通するので一箇所で設定するようにしました。

ここで読み込んでるのでファイル名は間違えないようしてください。

manifestについてはresourceDirは後述します。

実行構成

classpath設定

Projectのsrc/test/javaを右クリックしてRun->All TestsAndroidじゃないほう)を選択します。

f:id:STAR_ZERO:20140513185825p:plain

次のようなエラーになると思います。

!!! JUnit version 3.8 or later expected:

java.lang.RuntimeException: Stub!
    at junit.runner.BaseTestRunner.<init>(BaseTestRunner.java:5)
    at junit.textui.TestRunner.<init>(TestRunner.java:54)
    at junit.textui.TestRunner.<init>(TestRunner.java:48)
    at junit.textui.TestRunner.<init>(TestRunner.java:41)

これはclasspathの設定でAndroid側のJUnit3が先に設定されているのが原因です。なので、これを変更するようにします。

さっき実行した時の実行コンソールの一番うえに /System/Library/Java/JavaVirtualMachines/1.6.0.jdk/Contents/Home/bin/java -ea ...という箇所があると思いますが、その中にある -classpath "/Applications/Android Studio.app/lib/idea_rt.jar:..."というclasspathを設定してるところをコピーします。だいぶ長いです。

適当なエディタに貼り付けて <user home>/.gradle/caches/modules-2/files-2.1/junit/junit/4.11/4e031bb61df09069aeb2bffb4019e7a5034a4ee0/junit-4.11.jar:というJUnit4のjarの場所を切り取って、classpath設定の一番にまえに持っていきます。

こんな感じになります。 -classpath "<user home>/.gradle/caches/modules-2/files-2.1/junit/junit/4.11/4e031bb61df09069aeb2bffb4019e7a5034a4ee0/junit-4.11.jar:/Applications/Android Studio.app...

これをコピーしておきます。

メニューのRun->Edit Configurationsを選択します。左側でAll in appが選択されているをことを確認して、VM options:に先ほどのclasspath設定を貼り付けます。OKを押して変更を終了します。

f:id:STAR_ZERO:20140513190354p:plain

テストクラスのclasspath設定

ここまで来たらもう一度実行します。そうすると今度は次のようにテストクラスが無いって怒られます。

Class not found: "テストクラス名"

さきほど設定したclasspathのさらに一番後ろに<project path>/app/build/test-classesも追加しておきます。これはテストのclassファイルが作成されるディレクトリになります。

Working directory変更

Gradleから実行した時とAndroidStudioから実行した時にWorking directoryが異なるので、Gradle側に合わせておきます。

メニューのRun->Edit Configurationsを選択します。Working directoryの箇所を一階層したのappを指定します。OKを押して変更を終了します。

f:id:STAR_ZERO:20140513190540p:plain

Robolectric用の設定ファイルの補足

manifest

AndroidStudioから実行した時にうまくManifestファイルが見つけられないので指定しています。

resourceDir

resourceDirについては指定したmanifestからの相対パスになります。(ここハマりました…)

ここで指定してるのはすべてBuild後のファイルになってます。ビルド前のリソースsrc/main/resを指定しまうとsupport libraryから参照してるものが見つからなくてエラーになってしまいます。

java.lang.RuntimeException: huh? can't find parent for StyleData みたいなエラーが出た場合はresourceDirの指定が間違ってる可能性あります。

AndroidStudioからテストを実行する

Projectのsrc/test/javaを右クリックしてRun->All TestsAndroidじゃないほう)を選択してテストを実行します。ちゃんと設定されていればテストが実行されて結果が表示されるはずです。

  • テスト成功

f:id:STAR_ZERO:20140513191211p:plain

  • テスト失敗

f:id:STAR_ZERO:20140513191226p:plain

クラス単位でテストを実行する

実行構成のデフォルト設定

さっきまでの設定をテストクラスごとに毎回やるのは面倒なのでデフォルトに設定します。

メニューのRun->Edit Configurationsを選択します。

左側のDefaultsを展開して、JUnitを選択します。右側にさっきまでの設定でやったVM optionsWorking directoryを設定します。

f:id:STAR_ZERO:20140513193912p:plain

クラス単位で実行する

対象のテストクラスを右クリックしてRun->テストクラス名Androidじゃないほう)を選択します。これでクラス単位でテストが実行できます。

実行構成はさきほど設定したデフォルトのものが適用されています。

まとめ

結構面倒な感じですが、いちいちターミナルからテストを実行する必要がなくなり、クラス単位でのテスト実行もできるようになりました。

この設定でテスト書いていきたいと思います。