How do I add a new sourceset to Gradle? How do I add a new sourceset to Gradle? java java

How do I add a new sourceset to Gradle?


Update for 2021:

A lot has changed in 8ish years. Gradle continues to be a great tool. Now there's a whole section in the docs dedicated to configuring Integration Tests. I recommend you read the docs now.

Original Answer:

This took me a while to figure out and the online resources weren't great. So I wanted to document my solution.

This is a simple gradle build script that has an intTest source set in addition to the main and test source sets:

apply plugin: "java"sourceSets {    // Note that just declaring this sourceset creates two configurations.    intTest {        java {            compileClasspath += main.output            runtimeClasspath += main.output        }    }}configurations {    intTestCompile.extendsFrom testCompile    intTestRuntime.extendsFrom testRuntime}task intTest(type:Test){    description = "Run integration tests (located in src/intTest/...)."    testClassesDir = project.sourceSets.intTest.output.classesDir    classpath = project.sourceSets.intTest.runtimeClasspath}


Here is how I achieved this without using configurations{ }.

apply plugin: 'java'sourceCompatibility = JavaVersion.VERSION_1_6sourceSets {    integrationTest {        java {            srcDir 'src/integrationtest/java'        }        resources {            srcDir 'src/integrationtest/resources'        }        compileClasspath += sourceSets.main.runtimeClasspath    }}task integrationTest(type: Test) {    description = "Runs Integration Tests"    testClassesDir = sourceSets.integrationTest.output.classesDir    classpath += sourceSets.integrationTest.runtimeClasspath}

Tested using: Gradle 1.4 and Gradle 1.6


This was once written for Gradle 2.x / 3.x in 2016 and is far outdated!! Please have a look at the documented solutions in Gradle 4 and up


To sum up both old answers (get best and minimum viable of both worlds):

some warm words first:

  1. first, we need to define the sourceSet:

    sourceSets {    integrationTest}
  2. next we expand the sourceSet from test, therefor we use the test.runtimeClasspath (which includes all dependenciess from test AND test itself) as classpath for the derived sourceSet:

    sourceSets {    integrationTest {        compileClasspath += sourceSets.test.runtimeClasspath        runtimeClasspath += sourceSets.test.runtimeClasspath // ***)    }}
    • note) somehow this redeclaration / extend for sourceSets.integrationTest.runtimeClasspath is needed, but should be irrelevant since runtimeClasspath always expands output + runtimeSourceSet, don't get it
  3. we define a dedicated task for just running integration tests:

    task integrationTest(type: Test) {}
  4. Configure the integrationTest test classes and classpaths use. The defaults from the java plugin use the test sourceSet

    task integrationTest(type: Test) {    testClassesDir = sourceSets.integrationTest.output.classesDir    classpath = sourceSets.integrationTest.runtimeClasspath}
  5. (optional) auto run after test

    integrationTest.dependsOn test

  6. (optional) add dependency from check (so it always runs when build or check are executed)

    tasks.check.dependsOn(tasks.integrationTest)
  7. (optional) add java,resources to the sourceSet to support auto-detection and create these "partials" in your IDE. i.e. IntelliJ IDEA will auto create sourceSet directories java and resources for each set if it doesn't exist:

    sourceSets {     integrationTest {         java         resources     }}

tl;dr

apply plugin: 'java'// apply the runtimeClasspath from "test" sourceSet to the new one// to include any needed assets: test, main, test-dependencies and main-dependenciessourceSets {    integrationTest {        // not necessary but nice for IDEa's        java        resources        compileClasspath += sourceSets.test.runtimeClasspath        // somehow this redeclaration is needed, but should be irrelevant        // since runtimeClasspath always expands compileClasspath        runtimeClasspath += sourceSets.test.runtimeClasspath    }}// define custom test task for running integration teststask integrationTest(type: Test) {    testClassesDir = sourceSets.integrationTest.output.classesDir    classpath = sourceSets.integrationTest.runtimeClasspath}tasks.integrationTest.dependsOn(tasks.test)

referring to:

Unfortunatly, the example code on github.com/gradle/gradle/subprojects/docs/src/samples/java/customizedLayout/build.gradle or …/gradle/…/withIntegrationTests/build.gradle seems not to handle this or has a different / more complex / for me no clearer solution anyway!