はじめに
執筆時点では、robolectric 2.4 が最新バージョンであり、appcompat v7
ライブラリをサポートしていないことに注意してください。サポートは robolectric 3.0 リリースで追加される予定です (まだ ETA はありません)。またActionBar Sherlock
、robolectric で問題が発生する可能性があります。
Android Studio 内で Robolectric を使用するには、次の 2 つのオプションがあります。
(オプション 1) - Java モジュールを使用して Android Studio で JUnit テストを実行する
この手法では、Android モジュールに依存するすべてのテストに Java モジュールを使用し、魔法のようなカスタム テスト ランナーを使用します。
手順はこちらにあります: http://blog.blundellapps.com/how-to-run-robolectric-junit-tests-in-android-studio/
また、その投稿の最後にあるリンクをチェックして、Android Studio からテストを実行してください。
(オプション 2) - robolectric-gradle-plugin を使用して Android Studio で JUnit テストを実行する
Android Studio で gradle から実行するように junit テストを設定する際に、いくつかの問題が発生しました。
これは、 Android Studio で gradleベースのプロジェクトから junit テストを実行するための非常に基本的なサンプル プロジェクトです: https://github.com/hanscapelle/android-studio-junit-robolectric robolectric gradle プラグイン 0.13+ および robolectric 2.3
ビルドスクリプト (project/build.gradle)
ビルド スクリプトは、プロジェクトのルートにある build.gradle ファイルです。そこで、 robolectric gradle プラグインをクラスパスに追加する必要がありました
buildscript {
repositories {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.13.2'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files
classpath 'org.robolectric:robolectric-gradle-plugin:0.13.+'
}
}
allprojects {
repositories {
jcenter()
}
}
プロジェクトビルドスクリプト (App/build.gradle)
アプリ モジュールのビルド スクリプトでrobolectric
プラグインを使用し、robolectric
構成を追加してandroidTestCompile
依存関係を追加します。
apply plugin: 'com.android.application'
apply plugin: 'robolectric'
android {
// like any other project
}
robolectric {
// configure the set of classes for JUnit tests
include '**/*Test.class'
exclude '**/espresso/**/*.class'
// configure max heap size of the test JVM
maxHeapSize = '2048m'
// configure the test JVM arguments
jvmArgs '-XX:MaxPermSize=512m', '-XX:-UseSplitVerifier'
// configure whether failing tests should fail the build
ignoreFailures true
// use afterTest to listen to the test execution results
afterTest { descriptor, result ->
println "Executing test for {$descriptor.name} with result: ${result.resultType}"
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile 'org.robolectric:robolectric:2.3'
androidTestCompile 'junit:junit:4.10'
}
JUnit テスト クラスの作成
テストクラスをデフォルトの場所に配置します(またはgradle構成を更新します)
app/src/androidTest/java
そして、Test で終わるテスト クラスに名前を付け (または再度構成を更新し)、junit.framework.TestCase
テスト メソッドを拡張し、 で注釈を付けます@Test
。
package be.hcpl.android.mytestedapplication;
import junit.framework.TestCase;
import org.junit.Test;
public class MainActivityTest extends TestCase {
@Test
public void testThatSucceeds(){
// all OK
assert true;
}
@Test
public void testThatFails(){
// all NOK
assert false;
}
}
テストの実行
次に、コマンドラインからgradlewを使用してテストを実行します(chmod +x
必要に応じて使用して実行可能にします)
./gradlew clean test
出力例:
Executing test for {testThatSucceeds} with result: SUCCESS
Executing test for {testThatFails} with result: FAILURE
android.hcpl.be.mytestedapplication.MainActivityTest > testThatFails FAILED
java.lang.AssertionError at MainActivityTest.java:21
2 tests completed, 1 failed
There were failing tests. See the report at: file:///Users/hcpl/Development/git/MyTestedApplication/app/build/test-report/debug/index.html
:app:test
BUILD SUCCESSFUL
トラブルシューティング
代替ソース ディレクトリ
Java ソース ファイルを別の場所に置くことができるように、テスト ソース ファイルを移動することができます。gradle sourceSets
configを更新するだけです。
sourceSets {
main {
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
androidTest {
setRoot('tests')
}
}
パッケージ org.junit が存在しません
アプリのビルド スクリプトに junit テストの依存関係を追加するのを忘れた
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile 'org.robolectric:robolectric:2.3'
androidTestCompile 'junit:junit:4.10'
}
java.lang.RuntimeException: スタブ!
コマンドライン (Android Studio の [ターミナル] タブ) ではなく、Android Studio の実行構成を使用してこのテストを実行しています。Android Studio から実行するには、app.iml
ファイルを更新して、一番下に jdk エントリがリストされるようにする必要があります。詳細については、 deccard-gradle の例を参照してください。
完全なエラーの例:
!!! 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)
at com.intellij.rt.execution.junit.JUnitStarter.junitVersionChecks(JUnitStarter.java:190)
at com.intellij.rt.execution.junit.JUnitStarter.canWorkWithJUnitVersion(JUnitStarter.java:173)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:56)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:606)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
エラー: JAVA_HOME が無効なディレクトリに設定されています
解決策については、この SO の質問を参照してください。以下のエクスポートを bash プロファイルに追加します。
export JAVA_HOME=`/usr/libexec/java_home -v 1.7`
完全なエラー ログ:
ERROR: JAVA_HOME is set to an invalid directory: export JAVA_HOME=/Library/Java/JavaVirtualMachines/jdk1.7.0_51.jdk/Contents/Home
Please set the JAVA_HOME variable in your environment to match the
location of your Java installation.
テスト クラスが見つかりません
代わりに Android Studio Junit Test runner からテストを実行する場合は、Android Studio がコンパイル済みのテスト クラスを見つけられるように、build.gradle ファイルをもう少し拡張する必要があります。
sourceSets {
testLocal {
java.srcDir file('src/test/java')
resources.srcDir file('src/test/resources')
}
}
android {
// tell Android studio that the instrumentTest source set is located in the unit test source set
sourceSets {
instrumentTest.setRoot('src/test')
}
}
dependencies {
// Dependencies for the `testLocal` task, make sure to list all your global dependencies here as well
testLocalCompile 'junit:junit:4.11'
testLocalCompile 'com.google.android:android:4.1.1.4'
testLocalCompile 'org.robolectric:robolectric:2.3'
// Android Studio doesn't recognize the `testLocal` task, so we define the same dependencies as above for instrumentTest
// which is Android Studio's test task
androidTestCompile 'junit:junit:4.11'
androidTestCompile 'com.google.android:android:4.1.1.4'
androidTestCompile 'org.robolectric:robolectric:2.3'
}
task localTest(type: Test, dependsOn: assemble) {
testClassesDir = sourceSets.testLocal.output.classesDir
android.sourceSets.main.java.srcDirs.each { dir ->
def buildDir = dir.getAbsolutePath().split('/')
buildDir = (buildDir[0..(buildDir.length - 4)] + ['build', 'classes', 'debug']).join('/')
sourceSets.testLocal.compileClasspath += files(buildDir)
sourceSets.testLocal.runtimeClasspath += files(buildDir)
}
classpath = sourceSets.testLocal.runtimeClasspath
}
check.dependsOn localTest
から: http://kostyay.name/android-studio-robolectric-gradle-getting-work/
その他のリソース
これに関して私が見つけた最高の記事は次のとおりです。