@@ -28,6 +28,10 @@ node {
2828 download = true
2929}
3030
31+ if (! rootProject. ext. has(' testModuleSummaries' )) {
32+ rootProject. ext. testModuleSummaries = []
33+ }
34+
3135allprojects {
3236 apply plugin : ' java'
3337 apply plugin : ' java-library'
@@ -98,6 +102,38 @@ allprojects {
98102 description = ' Provides a complete report on project dependencies; use option (e.g.) --configuration compile to narrow'
99103 }
100104
105+ tasks. withType(Test ). configureEach { testTask ->
106+ afterSuite { desc , result ->
107+ if (! desc. parent) {
108+ // Store summary; do not print now
109+ rootProject. ext. testModuleSummaries << [
110+ projectPath : project. path,
111+ taskPath : testTask. path,
112+ resultType : result. resultType,
113+ executed : result. testCount,
114+ passed : result. successfulTestCount,
115+ failed : result. failedTestCount,
116+ skipped : result. skippedTestCount,
117+ durationMs : (result. endTime - result. startTime)
118+ ]
119+ }
120+ }
121+ }
122+ }
123+
124+ gradle. buildFinished { buildResult ->
125+ def summaries = rootProject. ext. has(' testModuleSummaries' ) ? rootProject. ext. testModuleSummaries : []
126+ if (! summaries || summaries. isEmpty()) {
127+ return
128+ }
129+ println " === All Module Test Summaries (${ buildResult.failure ? 'BUILD FAILURE' : 'BUILD SUCCESS'} ) ==="
130+ summaries. sort { it. projectPath }. each { s ->
131+ println " Module ${ s.projectPath} (${ s.taskPath} ): ${ s.resultType} - ${ s.executed} executed, ${ s.passed} passed, ${ s.failed} failed, ${ s.skipped} skipped in ${ s.durationMs} ms"
132+ }
133+ def total = summaries. inject([e :0 ,p :0 ,f :0 ,s :0 ,d :0 ]) { acc , m ->
134+ acc. e + = m. executed; acc. p + = m. passed; acc. f + = m. failed; acc. s + = m. skipped; acc. d + = m. durationMs; acc
135+ }
136+ println " === Aggregate Test Summary: ${ total.e} executed, ${ total.p} passed, ${ total.f} failed, ${ total.s} skipped (sum durations ${ total.d} ms) ==="
101137}
102138
103139/* ======== Child Projects ========*/
0 commit comments