用意するもの
- Androidプロジェクト
- Gradle (1.9) // 1.10 は Android Gradle Plugin が未対応
使うもの
- Android Gradle plugin
- Robolectric
- robolectric-plugin (修正版)
- groovy-base plugin (Gradle標準)
robolectric-plugin の問題
現在 sonatype のmaven repositoryで公開されている robolectric-plugin 0.0.1-SNAPSHOT (com.novoda.gradle:robolectric-plugin:0.0.1-SNAPSHOT) にはいくつか問題点があります。
- Windows環境下ではpluginロード時に例外発生 (半年も前にpull-reqされるも現時点で絶賛放置中の模様)
- androidのソースコードが 'src/main/java' にあること決め打ち
- テストの実行時ディレクトリが 'src/main' 固定
- debug build type のclasses しか参照しないのに assemble taskに依存しているため無駄に assembleRelease task が動く
上記の修正版の方はこれらの問題を修正したもの。適宜 git clone
して gradle install
してください。(この際、versionは0.0.1となる com.novoda.gradle:robolectric-plugin:0.0.1 )
groovy-base plugin について
Gradleにはgroovy plugin が標準で用意されているが、このgroovy pluginはjava pluginに依存している、一方Android Gradle plugin はjava plugin と共存不可能となっている。
groovy-base plugin は一応Gradleの公式Documentで紹介はされているが、詳細についてはundocumentedなpluginである。
Gradleのソースを確認したところ、java pluginに依存し、taskの依存関係を設定しているのが groovy plugin で、 groovy-base pluginはそれ以外の仕事を引き受けているようだった(compileSourceSetGroovy taskの生成など)
build.gradle 例
buildscript {
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
classpath 'com.android.tools.build:gradle:0.7.3'
classpath 'com.novoda.gradle:robolectric-plugin:0.0.1'
}
}
apply plugin: 'android'
apply plugin: 'robolectric'
apply plugin: 'groovy-base'
repositories {
mavenCentral()
mavenLocal()
}
dependencies {
robolectricCompile 'org.robolectric:robolectric:2.0'
robolectricCompile 'junit:junit:4.+'
robolectricCompile 'org.codehaus.groovy:groovy-all:2.2.0'
}
sourceSets {
robolectric {
java.srcDirs = ['test/java']
groovy.srcDirs = ['test/groovy']
resources.srcDirs = ['test/resources']
}
}
tasks.withType(Test) {
// avoid "> superClassName is empty!" error
scanForTestClasses = false
include "**/*Test.class"
exclude "**/Abstract*.class"
}
android {
compileSdkVersion 8
buildToolsVersion "19.0.0"
sourceSets {
main {
// Legacy構成 :)
manifest.srcFile 'AndroidManifest.xml'
java.srcDirs = ['src']
resources.srcDirs = ['src']
aidl.srcDirs = ['src']
res.srcDirs = ['res']
assets.srcDirs = ['assets']
}
}
// etc..
}
groovyのテストコード例
package test;
import com.example.android.Hoge;
import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
@Config(shadows=[org.robolectric.shadows.ShadowListView.class])
@RunWith(RobolectricTestRunner.class)
class HogeTest {
@Test
void testHoge()
throws Exception
{
def target = new Hoge();
// do test with target
}
}