Test your plugin against different versions of Gradle as part of your build.

Structure

Source directory layout
${projectDir} / src / gradleTest /  project1 / build.gradle
                                    project2 /
                                    project3 /

Each directory below gradleTest becomes a test. Tests are executed in-folder and expects a build.gradle file. If the latter is not found the test will not be executed.

For testing, a folder is created for each gradle version to be tested and the projects are duplicated below the verson folder. Each version testsute is executed within a separate JVM.

Test directory layout
${buildDir} / gradleTest / ver1 / project1 (1)
                                / project2
                                / project3
                         / ver2 / project1
                                / project2
                                / project3
                         / init.gradle     (2)
                         / repo            (3)
                         / home            (4)
            / classes / gradleTest         (5)
            / gradleDist                   (6)
1 Projects are duplicated for each Gradle version. See below for a more detailed layout
2 This is a generated initscript used to start all tests.
3 This is flat repository that can be utilised by all tests.
4 Gradle home directory for all the tests
5 Temporary classes for bootstrapping the tests are kept here.
6 Distributions are downloaded here if necessary
Test layout for one test
... / project1 / .gradle         (1)
               / src             (2)
               / build           (3)
               / build.gradle    (4)
               / settings.gradle (5)
1 Project cachedir is sent here
2 If the test project has any folders they will be copied here
3 It is recommended that the build directory not be changed and left as per default
4 build.gradle is required for the test to be executed. It must contain a task called runGradleTest.
5 If a test project does not have a settings.gradle file an empty one will be generated in the test folder

Bootstrap

GradleTest is available in the Gradle Plugins repository. To use it, add the following snippet into your build script.

buildscript {
  repositories {
    maven {
      url "https://plugins.gradle.org/m2/"         (1)
    }
  }

  dependencies {
    classpath 'org.ysb33r.gradle:gradletest:0.5.4' (2)
  }
}

apply plugin: 'org.ysb33r.gradletest'             (3)
1 Add the Gradle Plugins repository.
2 Add the last version as a buildscript dependency.
3 Apply the plugin.

Global Configuration

gradleLocations {
  searchGradleUserHome = true      (1)
  includeGradleHome = true         (2)
  searchGvm = true                 (3)
  download = true                  (4)
  downloadToGradleUserHome = false (5)
  useGradleSite = true             (6)
  uris                             (7)
  search                           (8)
}
1 Search Gradle home for Gradle installations.
2 Include the current GRADLE_HOME folder.
3 Search the GVM folder for Gradle installations
4 Download uninstalled version if online. These distributions will be placed in the appropriate location in gradle.gradleHome.
5 Place downloaded distributions in gradle.gradleUserHomeDir in the same way Gradle wrapper will do.
6 Download distribution from the global Gradle distribution site.
7 List additional URLs to search for Gradle distributions.
8 Search these additional folders for Gradle installations. Search will be performed both as if it a cache-style folder (aka gradleUserHome) or an installation-style folder (aka GVM_HOME).

Task Configuration

gradleTest {
  versions '2.2','2.4-beta1'   (1)

  initscript '/path/to/script' (2)
}
1 Test against the listed versions
2 All gradle tests are invoked with a default initscript. This can be changed by setting your own init script. This path is evaluated with project.file.

Start Parameters

  • If gradle is run with --offline, it will be passed to the Gradle.

  • --project-cache-dir is always set to at the start of the project in buildDir

  • --no-daemon is set, as we don;t want to clash with existing running daemons.

  • --full-stacktrace is set and output is captured to test report.

Task dependencies

Currently the gradleTest task is not linked to any other tasks. Run this as explicit task on the command-line or add your own task dependencies in your gradle script.

The reason for this is that it can be quite time-consuming testset to run. The typical case will be that the tests are only run close to release time. Some people might prefer to set install.dependsOn gradleTest rather than check.dependsOn gradleTest or build.dependsOn gradleTest.

Dependencies

Although gradle tests can download their own dependencies, this might consume unnecessary bandwidth and waste a lot of testing time. In order to combat this, any dependencies listed under gradleTest configuration will be downloaded and made available to the running gradle tests.

Define dependencies in build.gradle
dependencies {
  gradleTest 'commons-cli:commons-cli:1.2'
}

These dependencies then appear as a flatDir repository in the gradle test.

NOTE: It is not necessary to add your plugin to the dependencies. The output of the jar task is automatically added to the gradleTest configuration.

Configure test build.gradle for dependency
buildscript {
  dependencies {
    classpath ':gnumake:1.0.1' (1)
  }
}

dependencies {
  compile ':commons-cli:1.2' (2)
}
1 It is completely possible to add it to the buildscript for loading plugins
2 Load up any dependencies a per normal

NOTE:This repository is injected into the test using the default initscript. If you use your own initscript and still want to avail your own feature you’ll need to add the following to your initscript.

buildscript {
  repositories {
    flatDir {
      dirs
    }
  }
}

allprojects {
  repositories {
  }
}

Dynamic dependencies

Hard-coding the plugin version in to the build.gradle files of the gradleTest test fixtures is a maintenance pain. Therefore it is possible to write something like

buildscript {
  dependencies {
    classpath ':gnumake:%%VERSION%%'
  }
}

and the plugin will substitute the %%VERSION%% token with the version of your project.

Adding additional test tasks

It is possible to add additional test tasks beyond gradleTest, by doing

configurations {
  furtherTest
}

task furtherTest( type : org.ysb33r.gradle.gradletest.GradleTest ) {
  versions '2.2'
}

Test files should be placed under src/furtherTest using the same layout as described earlier. Dependencies should be listed under furtherTest configuration.

Global configuration is still read from gradleLocations project extension.

Awesomeness

This plugin is so awesome, it applies to itself and then runs a collection of tests - See gradle/self-reference.gradle on how this is done.

Known Limitations

Contributors