One of the features I like when working on a small library is continuous testing. I used to setup my IDE to re-run my tests whenever a file changes. This article describes how to setup this kind of testing with Gradle and JUnit.
Gradle can turn any build into a continuous build. Just run any target you want with the
Whenever a test file changes, Gradle will re-compile the whole project and run all tests. With the current Gradle changes to incremental build and the enhancements to compilation avoidance, the compile steps are usually very fast. This switch is usually enough for a small project.
However the tests run-time can be long and running only changed tests would improve productivity. In that case, Gradle AFAIK doesn’t offer anything out of the box. But it’s quite easy to add this functionality using a custom incremental task.
First, let’s start by extending the Gradle’s Test task and adding with the incremental inputs argument:
Well this doesn’t do anything, but run the tests. But it shows that it’s possible to override the original @TaskAction. The
inputs argument now gives us the ability to distinguish between two states:
- Something before the test task changed, therefore the task can’t be run incrementally
- Only the test classes changed, and in that case it will give us the list of changed files.
It also gives us the files which have been removed, but we don’t care about them. So let’s enhance the task:
In case the build is incremental at this point, we get our list of changes. To set them up for testing, we can use the Gradle’s ability to run only tests that pass a filter. The filter takes a class name in package.class format, but the incremental outputs give us files. We’ll have to change the file names into class names and strip the absolute path:
The first replace strips the file extension. The second then removes the path to the folder. The substring removes the first file separator and the last replace changes all file separators into dots. The classes then populate the set of filter patterns in
And that’s it. Add the task to the main gradle build file:
And run the build with:
When you change any of the classes, the tests will be re-run. If you change only a single test class, only that class will be run.