Create Test Report in Root Project with Gradle - kercheval/GradleCMPlugin GitHub Wiki
Normally, JUNITs for subprojects are run for each subproject with the test reports created in those subprojects. This works reasonably well if you are focusing on a specific subproject, but has some issues when dealing with the whole project or doing CI builds.
- Build failure on first JUNIT failure - The first problem is that, by default, Gradle builds will halt on the first JUNIT failure in a build and the report shows only a single failure. Typically, having a complete list of failed JUNIT tests is far more useful for resolution and debugging.
- Build failure on first subproject failure (JUNIT) - The second problem is that, when a subproject triggers a failure, other subprojects later in the task graph are not run. This means that there is not a clear understanding of the artifacts that are currently in a non-buildable state.
- Reporting is distributed - The last significant problem is that it is difficult to see holistically what is wrong with a project build in test from the root, you must visit each subproject build report directory individually.
This example shows a method to solve some of these issues. The basic approach is to create a test event filter that runs after a suite is completed and determines if there are failure and stores this state. To ensure that all JUNIT suites are run, this approach ignores JUNIT failures at each subproject and fails later at the end of the build. This does not affect build failure behavior for compilation, only test runs.
Note that this implementation assumes the presence of Gradle 1.4 since it is using the TestReport task introduced in that release. The technique is usable even when doing this using 1.3 and earlier methods (a task for the reader!).
//
// Add support for a global test report
//
task testReport(type: TestReport) {
setDescription('Generates a test report from all subproject test tasks')
setGroup(JavaBasePlugin.DOCUMENTATION_GROUP)
//
// Keep track of total failure count for later test and output
//
def testFailures = 0
//
// Place the output in the root build reports directory by default
//
destinationDir = file("$buildDir/reports/allTests")
//
// Include the results from the `test` task in all subprojects.
// The TestReport task does not handle things well if a subproject
// does not have the binary output, so this task assumes all subprojects
// include the gradle java plugin!
//
reportOn subprojects*.test
//
// Every subproject should ignore test failures, but here we add a
// test suite failure filter to ensure we keep track of the fact that
// failures have occurred (for the build failure check below)
//
subprojects {
test {
ignoreFailures true
afterSuite { td, tr ->
if (td.getParent() == null) {
testFailures += tr.getFailedTestCount()
}
}
}
}
//
// The last thing to do in this task is to check for failures.
// The build as a whole should fail if any tests failed.
//
doLast {
if (testFailures > 0) {
throw new Exception("There were ${testFailures} test failures")
}
}
}
//
// Add the test report to the dependency tree for a standard build
//
build.dependsOn(testReport)