Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Gradle - add dependency to tests of another module

I have a multi-module gradle project that looks like this:

Parent
|--server
|--application (android module)
+--common

The server tests have a dependency on the common module tests. For this, I added

testCompile files(project(':common').sourceSets.test.output.classesDi
compileTestJava.dependsOn tasks.getByPath(':common:testClasses')

and it worked great. Unfortunately, when I tried to do the same thing for the application module that also has a dependency on the common module tests, it wouldn't work. It fails with:

Build file 'application\build.gradle' line: 103
A problem occurred evaluating project ':application'.
 Could not find property 'sourceSets' on project ':common'

After googling a bit I also tried

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

But fails with another exception:

Project application: Only Jar-type local dependencies are supported. Cannot handle: common\build\classes\test

Any ideas on how to fix this?

like image 347
sakis kaliakoudas Avatar asked Jan 05 '16 01:01

sakis kaliakoudas


People also ask

What is testImplementation in gradle?

Configuration inheritance and composition For example the testImplementation configuration extends the implementation configuration. The configuration hierarchy has a practical purpose: compiling tests requires the dependencies of the source code under test on top of the dependencies needed write the test class.

What is subproject in gradle?

In a multi-project gradle build, you have a rootProject and the subprojects. The combination of both is allprojects. The rootProject is where the build is starting from. A common pattern is a rootProject has no code and the subprojects are java projects.


4 Answers

There's a couple of approaches solving the problem of importing test classes in this article. https://softnoise.wordpress.com/2014/09/07/gradle-sub-project-test-dependencies-in-multi-project-builds/ The one I used is:

code in shared module:

task jarTest (type: Jar) {
    from sourceSets.test.output
    classifier = 'test'
}

configurations {
    testOutput
}

artifacts {
    testOutput jarTest
}

code in module depending on the shared module: dependencies{ testCompile project(path: ':common', configuration: 'testOutput') }

And there seems to be a plugin for it as well! https://plugins.gradle.org/plugin/com.github.hauner.jarTest/1.0

like image 141
sakis kaliakoudas Avatar answered Oct 16 '22 04:10

sakis kaliakoudas


Following the approach from sakis, this should be the configuration you need to get the tests available from another project in the Android platform (done for debug variant). Shared module:

task jarTests(type: Jar, dependsOn: "assembleDebugUnitTest") {
    classifier = 'tests'
    from "$buildDir/intermediates/classes/test/debug"
}
configurations {
    unitTestArtifact
}
artifacts {
    unitTestArtifact jarTests
}

Your module:

dependencies {
    testCompile project(path: ":libName", configuration: "unitTestArtifact")
}
like image 42
droidpl Avatar answered Oct 16 '22 03:10

droidpl


I know it's kinda an old question but the solution mentioned in the following blog solves the problem very nicely and is not a sort of hack or a temporary workaround: Shared test sources in Gradle multi-module project

It works something like this:

// in your module's build.gradle file that needs tests from another module
dependencies {
    testCompile project(path: ':path.to.project', configuration: 'test')
}

Also you should note that in the very last paragraph he mentioned that you need to enable Create separate module per source set in IntelliJ settings. But it works fine without using that option too. Probably due to changes in the recent IntelliJ versions.

EDIT: IntelliJ recognizes this fine as of 2020.x versions.

like image 39
zaerymoghaddam Avatar answered Oct 16 '22 04:10

zaerymoghaddam


The solution mentioned by droidpl for Android + Kotlin looks like this:

task jarTests(type: Jar, dependsOn: "assembleDebugUnitTest") {
    getArchiveClassifier().set('tests')
    from "$buildDir/tmp/kotlin-classes/debugUnitTest"
}

configurations {
    unitTestArtifact
}

artifacts {
    unitTestArtifact jarTests
}

Gradle for project that is going to use dependencies:

testImplementation project(path: ':shared', configuration: 'unitTestArtifact')
like image 22
Nimdokai Avatar answered Oct 16 '22 04:10

Nimdokai