Cover Optimize & Gradle
Last updated
Last updated
Cover Optimize speeds up the time required to run Java unit tests by running only the tests in your project that are relevant to your code change. The Cover Optimize for Gradle plugin accepts a patch file, analyses the code change and determines which Java unit tests in your project need to be run in order to exercise the changes made by the patch.
To use the Cover Optimize for Gradle plugin, Cover CLI (release >= 2022.03.02) must be installed and activated with an appropriate license. Further installation details can be found here.
Diffblue Cover Optimize can be integrated into your CI with the help of the Cover Optimize for Gradle plugin. This plugin acts as a wrapper around the Cover CLI, invoking Diffblue Cover Optimize before the Gradle Test
task. The plugin calculates the impact of the patch file on your codebase and applies filters to the Test
task to ensure that Gradle only runs the tests relevant for the changes introduced.
To configure Diffblue Cover Optimize in your Gradle project you will need to update your build script (build.gradle
or build.gradle.kts
) to:
Install the Cover Optimize for Gradle plugin.
Configure the optimizeTests
task
The optimizeTests
task examines the code in your classpath to calculate the effects of your patch file. It passes the resulting test filters to the test
task via an accompanying task updateTestFilter
.
The following diagram shows the dependencies between these tasks required to add Diffblue Cover Optimize to your Gradle project:
Additionally optimizeTests
applies an internal dependency on compileTestJava
.
The Cover Optimize for Gradle plugin is distributed as a JAR file, available from the Diffblue Public Maven Repository.
To install the plugin into your project you will need to make changes to your build script:
Add the Diffblue Public Maven Repository as a buildscript
repository.
Add the plugin's JAR as a buildscript
dependency.
Activate the Cover Optimize for Gradle plugin.
The following detail is from an example Gradle build script which installs the Cover Optimize for Gradle plugin:
In the above example, you should replace [diffblue-cover-version]
with the version number of Diffblue Cover you are using (e.g. 2022.03.02
). Run dcover version
to determine your current installed version.
For more documentation on this process please review the Gradle documentation: Applying plugins with the buildscript block.
optimizeTests
TaskThe Cover Optimize for Gradle plugin supplies the optimizeTests
task which is run before the Gradle Test
task and identifies the unit tests which are required to test your patch file.
You also need to configure a series of Gradle properties to control the optimizeTests task from the command line.
To configure the optimizeTests
task you will again need to make changes to your build script:
Configure the optimizeTests
task to calculate the impact of the patch file on your codebase and select relevant test filters.
Configure an accompanying task updateTestFilter
to apply selected test filters.
Specify dependencies between the tasks to ensure they coordinate correctly with the Gradle Test
task.
Also specify Gradle properties to control the behaviour of the optimizeTests
from the command line.
The following snippet is from an example Gradle build script which configures the optimizeTests
task:
For the example build script above, we will use environment variables to pass the required absolute paths to the optimizeTests
task:
DIFFBLUE_COMMAND
The absolute path to the installed dcover
script.
DIFFBLUE_PATCH
The absolute path the patch file.
For example, in bash
run export DIFFBLUE_PATCH=/path/to/a/changes.patch
or in powershell
run $env:DIFFBLUE_PATCH=/path/to/a/changes.patch
.
As an alternative to using environment variables, you could choose to set these values directly in the optimizeTests
task, or by using Grade properties to be specified from the command line (-Pcom.diffblue.cover.command=/path/to/dcover -Pcom.diffblue.cover.patch=/path/to/a/changes.patch
):
The optimizeTest
will prefer settings set directly in the task to those set via environment variables.
You can check the value of all the parameters used by the plugin by displaying the Gradle info output, e.g. using --info
.
A Gradle multi-project build allows a series of Gradle subprojects to share common configuration.
If your multi-project build uses the subprojects {}
or allprojects {}
DSL constructs, then you may need configure the optimizeTests
task within these blocks.
For more documentation on this process please review the Gradle documentation: Cross project configuration
Test
typesIf you have introduced additional Test
types into your project, for example to support Integration Tests, then you should add these tasks as dependencies of updateTestFilter
.
For example, in the snippet below the user has added a custom Test
type to test only the utils
package using a test exclusion. They have registered an additional dependency on updateTestFilter
.
For more on how to specify Test
types, please review the Gradle documentation: Using additional test types Sample.
Notice in the example build script we use test filtering to replace all inclusion filters using filter.setIncludePatterns
with a series of class names selected by the optimizer for execution. If your Test
type uses test filter inclusions these may be overwritten. You may prefer to use test filter exclusions (filter.excludeTestsMatching
) which take precedence over inclusions. Or use Test inclusion/exclusion
by class file which is applied separately to test filters.
For more on test filtering, please review the Gradle documentation: Test filtering.
Before you begin the installation, please obtain the link to download Cover (from your product update email, or contact Diffblue). Please note you need version 2022.03.02 or above, installed and activated with an appropriate license.
For full details, please see: Installing Diffblue Cover in your CI environment.
Create a patch file called for example changes.patch
containing the changes you wish to run Diffblue Cover Optimize against. For examples on how to create a patch file from your changes using git, see Patch files.
For the example build script above we are relying upon environment variables to pass the absolute paths of the command and patch files to the plugin. An execution on bash
might looks like this:
Use the command gradle
if not using gradlew
. The --info
option can useful for debugging Gradle scripts and viewing output from Cover Optimize.
Only the tests that are impacted by the changes in the .patch
file will be run.
NOTE: Using a relative path such as ~/path/to/a/changes.patch
will not work, the path must be absolute.
In the example build script we have added the Gradle property skipTestOptimizer
to allow test optimization to be skipped, if the user so requires. In which case Gradle test
will execute without test optimization and without applying test filters:
All tests will be run without optimization.
For more on how to specify and use Gradle properties, please review the Gradle documentation: Gradle properties
--tests
option from the command lineThe Gradle --tests
option allows the user to specify additional test filters from the command line; these are applied in addition to and test inclusion/exclusion and test filtering specified within the build script:
When you use –tests, be aware that the inclusions declared in the build script are still honored. Test filtering.
As the test optimizer dynamically calculates test filters from your patch file, your --test
option may try to include or exclude tests which have not been selected by the optimizer, therefore no tests will be run.
If you wish to specify additional test filters via the --tests
option then it is recommended to skip test optimization when doing so:
For more on test filtering, please review the Gradle documentation: Test filtering.
There might be cases where Diffblue Cover Optimize does not select tests on certain changes as expected. It is easily possible to add custom rules to the configuration of the optimizeTests
task to instruct Diffblue Cover Optimize in these situations. For example:
The rules above mean that:
If there was a change to a pom.xml
file then all tests with the suffixes Test
and IT
will be run.
If there was a change to any file inside a resources
or projects
directory then all tests with suffixes IT
will be run. The matcher syntax uses glob patterns as used in Gradle to specify include patterns, for instance.
Custom rules are available from release 2022.05.02.