I’m trying to accelerate CI builds by not running tests for non-code changes, like a change to only README.md. I was hoping to be able to leverage the build cache for that, but unfortunately it behaves differently that I would expected. Here’s an example (with org.gradle.caching=true in gradle.properties):
First run in a clean tree:
$ git clean -fdx
$ ./gradlew scanner:funTest --tests com.here.ort.scanner.HttpCacheTest
...
:scanner:funTest
com.here.ort.scanner.HttpCacheTest > HttpCacheTest.HTTP GET returns what was PUT STARTED
com.here.ort.scanner.HttpCacheTest > HttpCacheTest.HTTP GET returns what was PUT PASSED
BUILD SUCCESSFUL in 9s
14 actionable tasks: 7 executed, 7 from cache
The tests runs, as expected. Then when executing the task again
the :scanner:funTest task is UP-TO-DATE, also as expected. However, if I clean the tree now and again run the task
$ git clean -fdx
$ ./gradlew scanner:funTest --tests com.here.ort.scanner.HttpCacheTest
...
:scanner:compileFunTestKotlin FROM-CACHE
...
:scanner:funTest
com.here.ort.scanner.HttpCacheTest > HttpCacheTest.HTTP GET returns what was PUT STARTED
com.here.ort.scanner.HttpCacheTest > HttpCacheTest.HTTP GET returns what was PUT PASSED
BUILD SUCCESSFUL in 8s
14 actionable tasks: 7 executed, 7 from cache
The :scanner:funTest task is run again, although for various other tasks before that I see FROM-CACHE. Why is there no FROM-CACHE from :scanner:funTest, to be consistent with the behavior of running the task two time in a row?
We hit exactly the same issue here, where the cache IDs were the same, and we’re using JaCoCo too, but we’re not happy to turn off coverage to get caching, and we do want to run tests in parallel.
I’ve done a bit of investigation and it seems like JaCoCo’s tasks already create a separate test report for each task, so the broken thing must be that when you run a single test task with the tests in parallel, it doesn’t cope with that parallelism.
Ah, I’m guessing the solution is to enhance the JaCoCo plugin to create an exec file per fork/test worker. These files would be merged together once all the tests are finished. That should yield a repeatable/cacheable result.
Another solution (that doesn’t require a JaCoCo plugin fix) is to use a single test worker (forkEvery 0) and append=false but I’m guessing that tests run too slowly in this scenario? In that case you could separate tests into separate projects which would allow gradle to run multiple test tasks in parallel (each with one fork/worker)
I put together a proof of concept which creates 10 “test-shard” projects, each has it’s own Test task which runs a subset of tests from the “all-tests” project. This allows each Test task to use append=false so that each is cacheable. Each Test task runs a single fork/testWorker but the test projects can be run in parallel. I’ve used a JacocoMerge task to merge the shards into a single report.
Interesting code at
I’ve tested this with the build cache and I can see the test results are cached correctly