Android Studio/IntelliJ
を使用して既存のAndroid
プロジェクトをビルドしており、簡単なJUnit
単体テストを追加したいと思います。そのようなテストを追加する適切なフォルダーは何ですか?
Android Gradle
プラグインは、メインソースコードにsrc/main/Java
、Android
テストにsrc/instrumentTest/Java
を使用してディレクトリ構造を定義します。
InstrumentTestにJUnitテストを追加しようとしてもうまくいきませんでした。 Android
テストとして実行できます(そのディレクトリの目的です)が、それは私が探しているものではありません-単純なJUnit
テストを実行したいだけです。このクラスのJUnit実行構成を作成しようとしましたが、それも機能しませんでした。ソースではなくAndroid
Testというフラグが付けられたディレクトリを使用しているためだと思います。
新しいソースフォルダーを作成し、Project Structureでそのようにマークすると、次回IntelliJ
がgradleビルドファイルからプロジェクト構成を更新します。
IntelliJ
のgradleベースのAndroidプロジェクトでJUnitテストを構成するより適切な方法は何ですか?これに使用するディレクトリ構造はどれですか?
Android Studio 1.1以降、答えは簡単になりました。 http://tools.Android.com/tech-docs/unit-testing-support
通常はできません。 Androidの世界へようこそ。Androidでは、すべてのテストをデバイスで実行する必要があります(Robolectricを除く)。
主な理由は、実際にフレームワークのソースを持っていないためです。IDEをテストしてローカルで実行するように説得しても、すぐに「スタブ!実装されていません」例外が発生します。 "なぜ?"あなたは疑問に思うかもしれません? SDKが提供するAndroid.jar
は実際にはすべてスタブ化されているためです。すべてのクラスとメソッドはありますが、例外をスローするだけです。 APIを提供するためのものですが、実際の実装を提供するためのものではありません。
Robolectric と呼ばれるすばらしいプロジェクトがあります。これは、意味のあるテストを実行できるように多くのフレームワークを実装しています。優れたモックフレームワーク(Mockitoなど)と組み合わせると、ジョブを管理しやすくなります。
Gradleプラグイン: https://github.com/robolectric/robolectric-gradle-plugin
執筆時点では、robolectric 2.4は最新バージョンであり、appcompat v7
ライブラリをサポートしていないことに注意してください。 robolectric 3.0リリースでサポートが追加されます(ETAはまだありません)。また、ActionBar Sherlock
は、robolectricで問題を引き起こす可能性があります。
Android Studio内でRobolectricを使用するには、2つのオプションがあります。
この手法では、Javaモジュールに依存するすべてのテストにAndroidモジュールを使用し、カスタムテストランナーにいくつかの魔法を使用します。
手順はここにあります: http://blog.blundellapps.com/how-to-run-robolectric-junit-tests-in-Android-studio/
また、Android studioからテストを実行するために、その投稿の最後にあるリンクを確認してください。
Android Studioのgradleから実行するようにjunitテストを設定する際にいくつかの問題が発生しました。
これは、Android Studioのgradleベースのプロジェクトからjunitテストを実行するための非常に基本的なサンプルプロジェクトです。 https://github.com/hanscappelle/Android-studio-junit-robolectric これは、Android Studio 0.8.14、JUnit 4.10、robolectric gradle plugin 0.13+およびrobolectric 2.3でテストされました
ビルドスクリプトは、プロジェクトのルートにあるbuild.gradleファイルです。そこで robolectric gradle plugin をクラスパスに追加する必要がありました
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()
}
}
アプリモジュールのビルドスクリプトで、robolectric
プラグインを使用して、robolectric
configを追加し、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'
}
次に、テストクラスをデフォルトの場所に配置します(またはgradle configを更新します)
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')
}
}
アプリのビルドスクリプトにjunitテストの依存関係を追加するのを忘れた
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
androidTestCompile 'org.robolectric:robolectric:2.3'
androidTestCompile 'junit:junit:4.10'
}
コマンドライン(Android Studioの[ターミナル]タブ)ではなく、Android Studioからの実行構成でこのテストを実行しています。 Android Studioから実行するには、app.iml
ファイルを更新して、jdkエントリを下部にリストする必要があります。詳細については deckard-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)
解決策については this SO question をご覧ください。以下のエクスポートを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テストランナーからテストを実行する場合、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
from: http://kostyay.name/Android-studio-robolectric-gradle-getting-work/
これについて私が見つけた最高の記事は次のとおりです。
これはAndroid Gradleプラグイン1.1.0以降のAndroid Studioでサポートされるようになりました。これをチェックしてください:
https://developer.Android.com/training/testing/unit-testing/local-unit-tests.html
GitHubのローカルユニットテストを使用したサンプルアプリ:
https://github.com/googlesamples/Android-testing/tree/master/unittesting/BasicSample
Android Studio 1.2 +の場合、JUnitのプロジェクトを設定するのは非常に簡単ですこのチュートリアルに従ってください:
これは、JUnitのプロジェクトを設定する最も簡単な部分です。
https://io2015codelabs.appspot.com/codelabs/Android-studio-testing#1
「 テストの実行 」まで、過去のリンクをたどります
ここで、インストルメンテーションテストと統合する場合は、次の手順に従ってください。
https://io2015codelabs.appspot.com/codelabs/Android-studio-testing#6
これをご覧ください tutorial Android Developers公式サイトから。この記事では、テスト用のモックアップを作成する方法も示します。
ところで、単純なJUnitテストの依存関係の範囲は "testCompile"であることに注意してください。