Gradle Test Dependency

TestingBuildAutomated TestsDependency ManagementGradle

Testing Problem Overview


I have two projects, project A and Project B. Both are written in groovy and use gradle as their build system.

Project A requires project B. This holds for both the compile and test code.

How can I configure that the test classes of project A have access to the test classes of project B?

Testing Solutions


Solution 1 - Testing

You can expose the test classes via a 'tests' configuration and then define a testCompile dependency on that configuration.

I have this block for all java projects, which jars all test code:

task testJar(type: Jar, dependsOn: testClasses) {
    baseName = "test-${project.archivesBaseName}"
    from sourceSets.test.output
}

configurations {
    tests
}

artifacts {
    tests testJar
}

Then when I have test code I want to access between projects I use

dependencies {
    testCompile project(path: ':aProject', configuration: 'tests')
}

This is for Java; I'm assuming it should work for groovy as well.

Solution 2 - Testing

This is a simpler solution that doesn't require an intermediate jar file:

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

There's more discussion in this question: https://stackoverflow.com/questions/5644011/multi-project-test-dependencies-with-gradle

Solution 3 - Testing

This works for me (Java)

// use test classes from spring-common as dependency to tests of current module
testCompile files(this.project(':spring-common').sourceSets.test.output)
testCompile files(this.project(':spring-common').sourceSets.test.runtimeClasspath)

// filter dublicated dependency for IDEA export
def isClassesDependency(module) {
     (module instanceof org.gradle.plugins.ide.idea.model.ModuleLibrary) && module.classes.iterator()[0].url.toString().contains(rootProject.name)
}
 
idea {
      module {
          iml.whenMerged { module ->
              module.dependencies.removeAll(module.dependencies.grep{isClassesDependency(it)})
              module.dependencies*.exported = true
          }
      }
  }
.....  
// and somewhere to include test classes 
testRuntime project(":spring-common")

Solution 4 - Testing

This is now supported as a first class feature in Gradle (since 5.6)

Modules with java or java-library plugins can also include a java-test-fixtures plugin which exposes helper classes and resources to be consumed with testFixtures helper. Benefit of this approach against artifacts and classifiers are:

  • proper dependency management (implementation/api)
  • nice separation from test code (separate source set)
  • no need to filter out test classes to expose only utilities
  • maintained by Gradle

Example:

:modul:one

modul/one/build.gradle

plugins {
  id "java-library" // or "java"
  id "java-test-fixtures"
}

dependencies {
  testFixturesImplementation("your.jar:dependency:0.0.1")
}

or lazyly just add all dependencies of main implementation configuration:

val testFixturesImplementation by configurations.existing
val implementation by configurations.existing
testFixturesImplementation.get().extendsFrom(implementation.get())

modul/one/src/testFixtures/java/com/example/Helper.java

package com.example;
public class Helper {}

:modul:other

modul/other/build.gradle

plugins {
  id "java" // or "java-library"
}
dependencies {
  testImplementation(testFixtures(project(":modul:one")))
}

modul/other/src/test/java/com/example/other/SomeTest.java

package com.example.other;
import com.example.Helper;
public class SomeTest {
  @Test void f() {
    new Helper(); // used from :modul:one's testFixtures
  }
}

For more info, see the documentation: https://docs.gradle.org/current/userguide/java_testing.html#sec:java_test_fixtures

Solution 5 - Testing

The above solution works, but not for the latest version 1.0-rc3 of Gradle.

     task testJar(type: Jar, dependsOn: testClasses) {
       baseName = "test-${project.archivesBaseName}"

       // in the latest version of Gradle 1.0-rc3
       // sourceSets.test.classes no longer works
       // It has been replaced with 
       // sourceSets.test.output

       from sourceSets.test.output
     }

   

Solution 6 - Testing

If ProjectA contains the test code you wish to use in ProjectB and ProjectB wants to use artifacts to include the test code, then ProjectB's build.gradle would look like this:

dependencies {

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

}

Then you need to add an archives command to the artifacts section in ProjectA's build.gradle:

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

configurations {
    tests
}

artifacts {
    tests testsJar
    archives testsJar
}

jar.finalizedBy(testsJar)

Now when ProjectA's artifacts are published to your artifactory they will include a -tests jar. This -tests jar can then be added as a testCompile dependency for ProjectB (as shown above).

Solution 7 - Testing

For Gradle 1.5

task testJar(type: Jar, dependsOn: testClasses) {
    from sourceSets.test.java
    classifier "tests"
}

Solution 8 - Testing

For Android on the latest gradle version (I'm currently on 2.14.1) you just need to add the below in Project B to get all the test dependencies from Project A.

dependencies {
  androidTestComplie project(path: ':ProjectA')
}

Solution 9 - Testing

dependencies {    
    testImplementation project(':project_name')
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionDr. Simon HarrerView Question on Stackoverflow
Solution 1 - TestingDavid ResnickView Answer on Stackoverflow
Solution 2 - TestingKipView Answer on Stackoverflow
Solution 3 - TestingMichail NikolaevView Answer on Stackoverflow
Solution 4 - TestingDirk HoffmannView Answer on Stackoverflow
Solution 5 - TestingzwesselsView Answer on Stackoverflow
Solution 6 - TestingJoman68View Answer on Stackoverflow
Solution 7 - TestingRobin ElvinView Answer on Stackoverflow
Solution 8 - TestingsantugowdaView Answer on Stackoverflow
Solution 9 - TestingSan JaisyView Answer on Stackoverflow