OK now it makes sense! The reason that you’re seeing this behaviour is because you effectively have 2 projects generating test reports into the same directory: the ‘root’ project and the ‘:one’ subproject.
Ignoring the fact that maybe gradle shouldn’t generate a test report for the root project that has no tests, it makes sense that the ‘test’ task checks if it’s outputs have changed, and re-executes if they have. Although in this case this could be fixed by using ‘subprojects’ instead of ‘allprojects’, you’re likely to have multiple subprojects in a real multiproject build, so this isn’t really a solution.
So until gradle supports this sort of test aggregation in the wild, you’ll need to code up a task to do this yourself.
We have something that does this in the gradle build:
task aggregateTestReports(type: TestReportAggregator) {
testReportDir = file("${reportsDir}/tests")
testResultsDir = file("${buildDir}/test-results")
projects = subprojects
}
class TestReportAggregator extends Copy {
def projects
File testResultsDir
@OutputDirectory
File testReportDir
def TestReportAggregator() {
dependsOn { testTasks }
from { inputTestResultDirs }
into { testResultsDir }
}
@TaskAction
def aggregate() {
def report = new org.gradle.api.internal.tasks.testing.junit.report.DefaultTestReport(testReportDir: testReportDir, testResultsDir: testResultsDir)
report.generateReport()
}
def getTestTasks() {
projects.collect { it.tasks.withType(Test) }.flatten()
}
def getInputTestResultDirs() {
testTasks*.testResultsDir
}
}
Note that this example uses an internal class ‘DefaultTestReport’, so the api may change in the future.