web-dev-qa-db-ja.com

gradleを使用したマルチプロジェクトテストの依存関係

マルチプロジェクト構成があり、gradleを使用したい。

私のプロジェクトは次のようなものです。

  • プロジェクトA

    • -> src/main/Java
    • -> src/test/Java
  • プロジェクトB

    • -> src/main/JavaプロジェクトAsrc/main/Javaに依存)
    • -> src/test/JavaプロジェクトAsrc/test/Javaに依存)

私のプロジェクトBbuild.gradleファイルは次のようなものです。

apply plugin: 'Java'
dependencies {
  compile project(':ProjectA')
}

タスクcompileJavaはうまく機能しますが、compileTestJavaProject Aからテストファイルをコンパイルしません。

126
mathd

非推奨

プロジェクトBでは、testCompile依存関係を追加するだけです。

dependencies {
  ...
  testCompile project(':A').sourceSets.test.output
}

Gradle 1.7でテスト済み。

109
Fesler

簡単な方法は、ProjectBに明示的なタスク依存関係を追加することです。

compileTestJava.dependsOn tasks.getByPath(':ProjectA:testClasses')

難しい(ただしより明確な)方法は、ProjectAの追加のアーティファクト構成を作成することです。

task myTestsJar(type: Jar) { 
  // pack whatever you need...
}

configurations {
  testArtifacts
}

artifacts {
   testArtifacts myTestsJar
}

projectBのtestCompile依存関係を追加します

apply plugin: 'Java'
dependencies {
  compile project(':ProjectA')
  testCompile project(path: ':ProjectA', configuration: 'testArtifacts')
}
55

私はそれが古い質問であることを知っていますが、私はちょうど同じ問題を抱えていて、何が起こっているかを理解するのにいくらかの時間を費やしました。 Gradle 1.9を使用しています。すべての変更はProjectBのbuild.gradleにある必要があります

ProjectBのテストでProjectAのテストクラスを使用するには:

testCompile files(project(':ProjectA').sourceSets.test.output.classesDir)

ProjectAでsourceSetsプロパティが使用可能であることを確認するには:

evaluationDependsOn(':ProjectA')

ProjectBをコンパイルするときに、ProjectAのテストクラスが実際に存在することを確認するには:

compileTestJava.dependsOn tasks.getByPath(':ProjectA:testClasses')
17
Dominik Pawlak

私は最近この問題に自分自身で遭遇しました、そして、人は答えを見つけるのが難しい問題です。

あなたが犯している間違いは、プロジェクトが主要なアーティファクトと依存関係をエクスポートするのと同じ方法でプロジェクトがテスト要素をエクスポートする必要があると考えていることです。

個人的にもっと成功したのは、Gradleで新しいプロジェクトを作成することでした。あなたの例では、私はそれに名前を付けます

プロジェクトA_Test-> src/main/Java

プロジェクトA/src/test/Javaに現在あるファイルをsrc/main/Javaに入れます。プロジェクトAのtestCompile依存関係を作成し、プロジェクトA_Testの依存関係をコンパイルします。

次に、プロジェクトA_TestをプロジェクトBのtestCompile依存関係にします。

両方のプロジェクトの作成者の観点から考えると論理的ではありませんが、junitやscalatest(およびその他)のようなプロジェクトについて考えると、非常に理にかなっていると思います。これらのフレームワークはテスト関連ですが、独自のフレームワーク内の「テスト」ターゲットの一部とは見なされません-他のプロジェクトがたまたまテスト構成内で使用する主要なアーティファクトを生成します。

ここにリストされている他の回答をしようとしても個人的にはうまくいきませんでした(Gradle 1.9を使用)が、ここで説明するパターンはとにかくきれいなソリューションであることがわかりました。

14
Martin Snyder

Gradleプラグインとして利用可能な新しいtestJarベースの(過渡的な依存関係をサポート)ソリューション:

https://github.com/hauner/gradle-plugins/tree/master/jartest

https://plugins.gradle.org/plugin/com.github.hauner.jarTest/1.

ドキュメントから

複数プロジェクトのgradleビルドを使用している場合、サブプロジェクト間にテストの依存関係がある可能性があります(おそらく、プロジェクトが適切に構造化されていないことのヒントです)。

たとえば、サブプロジェクトProject BがProject Aに依存し、BがAにコンパイル依存関係だけでなく、テスト依存関係も持っているプロジェクトを想定します。 Bのテストをコンパイルして実行するには、Aのテストヘルパークラスが必要です。

デフォルトでは、gradleはプロジェクトのテストビルド出力からjarアーティファクトを作成しません。

このプラグインは、testArchives構成(testCompileに基づく)およびjarTestタスクを追加して、テストソースセットからjarを作成します(jarの名前に分類子テストを追加)。次に、AのtestArchives構成に依存することができます(Aの推移的な依存関係も含まれます)。

Aでは、build.gradleにプラグインを追加します。

apply plugin: 'com.github.hauner.jarTest'

Bでは、testArchives構成を次のように参照します。

dependencies {
    ...
    testCompile project (path: ':ProjectA', configuration: 'testArchives') 
}
11
demon101

以下のアップデートをお読みください。

JustACluelessNewbieで説明されている同様の問題は、IntelliJ IDEAで発生します。問題は、依存関係testCompile project(':core').sourceSets.test.outputが実際には「gradleビルドタスクによって生成されたクラスに依存する」ことを意味することです。したがって、クラスがまだ生成されていないクリーンなプロジェクトを開くと、IDEAはそれらを認識せず、エラーを報告します。

この問題を解決するには、コンパイル済みクラスへの依存関係の隣にテストソースファイルへの依存関係を追加する必要があります。

// First dependency is for IDEA
testCompileOnly files { project(':core').sourceSets.test.Java.srcDirs }
// Second is for Gradle
testCompile project(':core').sourceSets.test.output

Module Settings-> Dependencies(test scope)でIDEAによって認識される依存関係を確認できます。

ところでこれはニースのソリューションではないため、リファクタリングを検討する価値があります。 Gradle自体には、テストサポートクラスのみを含む特別なサブプロジェクトがあります。 https://docs.gradle.org/current/userguide/test_kit.html を参照してください

2016年6月5日更新提案されたソリューションについてはあまり考えていません。それにはいくつかの問題があります:

  1. IDEAに2つの依存関係を作成します。 1つはテストソースを、もう1つはコンパイルされたクラスを指します。そして、IDEAがこれらの依存関係を認識する順序は重要です。 [モジュールの設定]-> [依存関係]タブで依存関係の順序を変更することで、それを試すことができます。
  2. これらの依存関係を宣言すると、依存関係構造を不必要に汚染することになります。

それでは、より良い解決策は何ですか?私の意見では、新しいカスタムソースセットを作成し、それに共有クラスを配置します。実際、Gradleプロジェクトの作成者は、testFixturesソースセットを作成してそれを行いました。

それをするためにあなたはただする必要があります:

  1. ソースセットを作成し、必要な構成を追加します。 Gradleプロジェクトで使用されるこのスクリプトプラグインを確認してください: https://github.com/gradle/gradle/blob/v4.0.0/gradle/testFixtures.gradle
  2. 依存プロジェクトで適切な依存関係を宣言します。

    dependencies {
        testCompile project(path: ':module-with-shared-classes', configuration: 'testFixturesUsageCompile')
    }
    
  3. GradleプロジェクトをIDEAにインポートし、インポート中に「ソースセットごとに個別のモジュールを作成」​​オプションを使用します。
9
Václav Kužel

Androidプロジェクト(gradle 2.2.0)をビルドしようとしたときに、Feslerのソリューションはうまくいきませんでした。したがって、必要なクラスを手動で参照する必要がありました:

Android {
    sourceSets {
        androidTest {
            Java.srcDir project(':A').file("src/androidTest/Java")
        }
        test {
            Java.srcDir project(':A').file("src/test/Java")
        }
    }
}
7
Beloo

私はパーティーにとても遅れています(現在はGradle v4.4です)が、これを見つけた他の人には:

想定:

~/allProjects
|
|-/ProjectA/module-a/src/test/Java
|
|-/ProjectB/module-b/src/test/Java

プロジェクトB(Aからのテストクラスを必要とするもの)のbuild.gradleに移動し、次を追加します。

sourceSets {
    String sharedTestDir = "${projectDir}"+'/module-b/src/test/Java'
    test {
        Java.srcDir sharedTestDir
    }
}

または(プロジェクトの名前が「ProjectB」であると仮定)

sourceSets {
    String sharedTestDir = project(':ProjectB').file("module-b/src/test/Java")
    test {
        Java.srcDir sharedTestDir
    }
}

出来上がり!

3
tricknology

テスト間で共有する必要がある模擬依存関係がある場合は、新しいプロジェクトprojectA-mockを作成し、それをProjectAおよびProjectBにテスト依存関係として追加できます。

dependencies {
  testCompile project(':projectA-mock')
}

これは、モック依存関係を共有するための明確なソリューションですが、ProjectA in ProjectBからテストを実行する必要がある場合は、他のソリューションを使用してください。

2
sylwano

他の回答のいくつかは何らかの方法でエラーを引き起こしました-Gradleは他のプロジェクトからのテストクラスを検出しなかったか、Eclipseプロジェクトがインポート時に無効な依存関係を持っていました。誰かが同じ問題を抱えている場合、私は一緒に行くことをお勧めします:

testCompile project(':core')
testCompile files(project(':core').sourceSets.test.output.classesDir)

最初の行は、Eclipseが他のプロジェクトを依存関係としてリンクするように強制するため、すべてのソースが含まれ、最新の状態になります。 2番目の方法では、Gradleがソースを実際に見ることができますが、testCompile project(':core').sourceSets.test.outputのような無効な依存関係エラーは発生しません。

2

artifact依存関係を使用する場合:

  • ProjectBのソースクラスは、Project Aのソースクラスに依存しています
  • ProjectBのテストクラスは、Project Aのテストクラスに依存しています

build.gradleのProjectBの依存関係セクションは次のようになります。

dependencies {

  compile("com.example:projecta:1.0.0")

  testCompile("com.example:projecta:1.0.0:tests")

}

これが機能するには、ProjectAが-tests jarをビルドし、生成するアーティファクトに含める必要があります。

ProjectAのbuild.gradleには、次のような構成が含まれている必要があります。

task testsJar(type: Jar, dependsOn: testClasses) {
    classifier = 'tests'
    from sourceSets.test.output
}

configurations {
    tests
}

artifacts {
    tests testsJar
    archives testsJar
}

jar.finalizedBy(testsJar)

ProjectAのアーティファクトがアーティファクトに公開されると、-tests jarが含まれます。

ProjectBの依存関係セクションのtestCompileは、-tests jarのクラスを取り込みます。


includeFlat開発目的でProjectBのProjectAのソースクラスとテストクラスを使用する場合、ProjectBのbuild.gradleの依存関係セクションは次のようになります。

dependencies {

  compile project(':projecta')

  testCompile project(path: ':projecta', configuration: 'tests')

}
2
Joman68