This was recently the topic on Gradle's blog post Stop rerunning your tests. The author shows an example using outputs.upToDateWhen { false }
and explains why it is wrong:
This doesn’t actually force reruns
What the author of this snippet probably wanted to say is “Always rerun my tests”. That’s not what this snippet does though. It will only mark the task out-of-date, forcing Gradle to recreate the output. But here’s the thing, if the build cache is enabled, Gradle doesn’t need to run the task to recreate the output. It will find an entry in the cache and unpack the result into the test’s output directory.
The same is true for this snippet:
test.dependsOn cleanTest
Gradle will unpack the test results from the build cache after the output has been cleaned, so nothing will be rerun. In short, these snippets are creating a very expensive no-op.
If you’re now thinking “Okay, I’ll deactivate the cache too”, let me tell you why you shouldn’t.
Then, the author goes on to explain why rerunning some tests is a waste of time:
The vast majority of your tests should be deterministic, i.e. given the same inputs they should produce the same result.
In the few cases where you do want to rerun tests where the code has not changed, you should model them as an input. Here are both examples from the blog post that show adding an input so the task will use it during its up-to-date checks.
task randomizedTest(type: Test) {
systemProperty "random.testing.seed", new Random().nextInt()
}
task systemIntegrationTest(type: Test) {
inputs.property "integration.date", LocalDate.now()
}
I recommend reading the entire blog post.