2013-05-20 14 views
30

私は新しいGradle Androidビルドシステムと一緒にRobolectricテストを実行しようとしていますが、私はメインプロジェクトのリソースにアクセスできません。Robolectric with Gradle:リソースが見つかりません

ディレクトリ構造はおおよそ次のようになりますので、私は、javaandroidのGradleプラグインの間の競合を回避するために、2つの別々のプロジェクトにビルドを分割:

. 
├── build.gradle 
├── settings.gradle 
├── mainproject 
│   ├── build 
│   │   ├── classes 
│   │   │   └── debug 
│   ├── build.gradle 
│   └── src 
│    └── main 
│     ├── AndroidManifest.xml 
│     └── ... 
└── test 
    ├── build.gradle 
    └── src 
       └── test 
        └── java 
         └── ... 
       └── test 
        ├── MainActivityTest.java 
        ├── Runner.java 
        ├── ServerTestCase.java 
        └── StatusFetcherTest.java 

test/マイbuild.gradleは現在、次のようになります。

buildscript { 
    repositories { 
     mavenCentral() 
    } 

    dependencies { 
     classpath 'com.stanfy.android:gradle-plugin-java-robolectric:2.0' 
    } 
} 

apply plugin: 'java-robolectric' 

repositories {...} 

javarob { 
    packageName = 'com.example.mainproject' 
} 

test { 
    dependsOn ':mainproject:build' 
    scanForTestClasses = false 
    include "**/*Test.class" 
    // Oh, the humanity! 
    def srcDir = project(':mainproject').android.sourceSets.main.java.srcDirs.toArray()[0].getAbsolutePath() 
    workingDir srcDir.substring(0, srcDir.lastIndexOf('/')) 
} 

project(':mainproject').android.sourceSets.main.java.srcDirs.each {dir -> 
    def buildDir = dir.getAbsolutePath().split('/') 
    buildDir = (buildDir[0..(buildDir.length - 4)] + ['build', 'classes', 'debug']).join('/') 

    sourceSets.test.compileClasspath += files(buildDir) 
    sourceSets.test.runtimeClasspath += files(buildDir) 
} 

dependencies {  
    testCompile group: 'com.google.android', name: 'android', version: '4.1.1.4' 
    testCompile group: 'org.robolectric', name: 'robolectric', version: '2.0-alpha-3' 
    ... 
} 

Rを除いて、私のメインプロジェクトのすべてのクラスにアクセスすることができます。.classビルドディレクトリ内のファイルが、compileTestJava作業中にこのエラーが発生します:

/.../MainActivityTest.java:16: error: cannot find symbol 
       final String appName = activity.getResources().getString(R.string.app_name); 
                     ^
    symbol: variable string 
    location: class R 
1 error 
:test:compileTestJava FAILED 

は右、新しいビルドシステムとRobolectricテストを実行するためのより良い方法があるに違いありませんか?

Full source of the app

+2

私はこれがうまくいくとは思わない。robolectricには、gradleプラグインの機能とはうまくいかない実際のリソース(依存関係を持つプロジェクトに拡張する)をどこで見つけるかについての、他の内部的なものがあります。 私はRobolectric開発者と協力して互換性を持たせる必要があります。それは私のやるべきことのリストです。 –

+0

入力ありがとう、@ Xav。 – passy

+0

新しいAndroid Studio ideでgradoを使ってrobolectricを実行する方法はまだありますか? – Imanol

答えて

27

私はこの同じ問題渡って走っていたし、これは私が思い付いたものです。テスト用の別のプロジェクトを作成する代わりに、私はRobolectricテスト用のソースセットを作成し、それに依存する新しいタスクを追加しました。私は私の依存関係を含めました

apply plugin: 'android' 

sourceSets { 
    testLocal { 
     java.srcDir file('src/test/java') 
     resources.srcDir file('src/test/resources') 
    } 
} 

dependencies { 
    compile 'org.roboguice:roboguice:2.0' 
    compile 'com.google.android:support-v4:r6' 

    testLocalCompile 'junit:junit:4.8.2' 
    testLocalCompile 'org.robolectric:robolectric:2.1' 
    testLocalCompile 'com.google.android:android:4.0.1.2' 
    testLocalCompile 'com.google.android:support-v4:r6' 
    testLocalCompile 'org.roboguice:roboguice:2.0' 
} 

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 

ために、私はこれを取得するためにことを指摘してブロックし、行く:あなたの質問からコードの一部を使用して、ここで構築(作業)ファイルの関連ビットは、私は自分のcompileの依存関係を私のカスタムtestLocalソースセットにすべて繰り返さなければならなかった。

gradle testLocalを実行すると、ビルドされ、gradle check実行デフォルトのAndroid instrumentTestソースセットのものに加えて、これらのテストを実行している間、src/test/javaの内部だけでテストを実行します。

希望すると便利です。

+0

これは正しい方向への巨大なステップのようです。 Robolectricテストランナーが実行されていますが、リソースにアクセスしようとすると、 "android.content.res.Resources $ NotFoundException:unknown resource xxx"が表示されます。ここでは完全なスタックトレース:https://gist.github.com/passy/255bbd42ada11ad5fba7 – passy

+1

これは、テストランナーは 'のsrc/main'にある' AndroidManifest.xml'を、見つけることができないことから来ているようです。私はRobolectricTestRunnerサブクラスでこれらのパスを設定できると思いますが、Eclipseではメインディレクトリに作業ディレクトリを設定します。私はgradleファイルでそれを行うことはできますか? – passy

+1

@passy残念ながら、私はその問題が出てくるのを見ていません。アンドロイド '{ sourceSets {メイン { :しかし、あなたはマニフェストbuild.gradle''でこれに似た何かをすることによって設定されたソースをプロジェクトディレクトリのルートにあなたの 'AndroidManifest.xml'を入れて、上書きすることができるはずですmanifest.srcFile 'のAndroidManifest.xml'}}} '出典:http://tools.android.com/tech-docs/new-build-system/user-guide – user2457888

8

更新: Jake Whartonはちょうどgradle-android-test-pluginを発表しました。 https://github.com/square/gradle-android-test-plugin

特に、robolectricを使用する予定がある場合、かなり合理化されているようです。

robolectric-plugin以下


古い回答は有望に見えます。

それらが提供するサンプルbuild.gradleファイルは次のとおりです。

buildscript { 
    repositories { 
     mavenCentral() 
     maven { 
      url "https://oss.sonatype.org/content/repositories/snapshots" 
     } 
    } 
    dependencies { 
     classpath 'com.android.tools.build:gradle:0.4.2' 
     classpath 'com.novoda.gradle:robolectric-plugin:0.0.1-SNAPSHOT' 
    } 
} 

apply plugin: 'android' 
apply plugin: 'robolectric' 

repositories { 
    mavenCentral() 
    mavenLocal() 
    maven { 
     url "https://oss.sonatype.org/content/repositories/snapshots" 
    } 
} 

dependencies { 
    //compile files('libs/android-support-v4.jar') 

    // had to deploy to sonatype to get AAR to work 
    compile 'com.novoda:actionbarsherlock:4.3.2-SNAPSHOT' 

    robolectricCompile 'org.robolectric:robolectric:2.0' 
    robolectricCompile group: 'junit', name: 'junit', version: '4.+' 
} 

android { 
    compileSdkVersion 17 
    buildToolsVersion "17.0.0" 

    defaultConfig { 
     minSdkVersion 7 
     targetSdkVersion 17 
    } 
} 

AndroidのGradleプラグインのバージョン0.5で動作するようには思えませんが、多分それはすぐになります。

+0

buildypeで分割されたリソースをサポートするJakeのプラグインを心待ちにしています。現在、それを扱うことはできません。誰かが(数ヶ月前に)これを修正するためのパッチを書いたが、それに関するコメントはなく、受け入れられていない。それまでは、受け入れられた回答のメソッドが機能しています。 –

+2

Jake Whartonのプラグインは廃止されましたか? – Flame

+0

はい、そうです。標準的なアンドロイドテストインフラストラクチャに移行するために慌てているようです。 Robolectricは依然として役に立ちますが、純粋なJavaクラスのほとんどがjunitでユニットテストされたJavaライブラリモジュールであり、アンドロイドのテストフレームワークではAndroid固有のものです。 –

関連する問題