Dr. Simon Harrer
Dr. Simon Harrer

Reputation: 1954

Gradle Test Dependency

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?

Upvotes: 86

Views: 72293

Answers (9)

San Jaisy
San Jaisy

Reputation: 17138

dependencies {    
    testImplementation project(':project_name')
}

Upvotes: 0

Dirk Hoffmann
Dirk Hoffmann

Reputation: 1573

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

Upvotes: 14

Joman68
Joman68

Reputation: 2850

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).

Upvotes: 5

santugowda
santugowda

Reputation: 9

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')
}

Upvotes: 0

Kip
Kip

Reputation: 109503

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: Multi-project test dependencies with gradle

Upvotes: 20

Robin Elvin
Robin Elvin

Reputation: 1255

For Gradle 1.5

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

Upvotes: 0

Michail Nikolaev
Michail Nikolaev

Reputation: 3775

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")

Upvotes: 8

David Resnick
David Resnick

Reputation: 4991

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.

Upvotes: 109

zwessels
zwessels

Reputation: 637

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
     }

Upvotes: 5

Related Questions