compileTestJava.dependsOn compileJava
-ext.testsFailed = false
/* testTask0 is the main test task */
task testTask0(type: Test) {
group = "Verification"
import groovy.time.TimeCategory
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
import org.gradle.api.tasks.testing.logging.TestLogEvent
-
rootProject.ext.testsResults = [] // Container for tests summaries
tasks.withType(Test).matching {t -> t.getName().startsWith("testTask")}.all { testTask ->
if (desc.parent) return // Only summarize results for whole modules
- String summary = "${testTask.project.name}:${testTask.name} results: ${result.resultType} " +
- "(" +
- "${result.testCount} tests, " +
- "${result.successfulTestCount} successes, " +
- "${result.failedTestCount} failures, " +
- "${result.skippedTestCount} skipped" +
- ") " +
- "in ${TimeCategory.minus(new Date(result.endTime), new Date(result.startTime))}" +
- "\n" +
- "Report file: ${testTask.reports.html.entryPoint}"
-
- // Add reports in `testsResults`, keep failed suites at the end
- if (result.resultType == TestResult.ResultType.SUCCESS) {
- rootProject.ext.testsResults.add(0, summary)
- } else {
- rootProject.ext.testsResults += summary
- }
+ def resultsInfo = [testTask.project.name, testTask.name, result, TimeCategory.minus(new Date(result.endTime), new Date(result.startTime)), testTask.reports.html.entryPoint]
- if (result.resultType == TestResult.ResultType.FAILURE) {
- testsFailed = true
- }
+ rootProject.ext.testsResults.add(resultsInfo)
}
// from original test task
if (!allResults.isEmpty()) {
printResults allResults
+ allResults.each {r ->
+ if (r[2].resultType == TestResult.ResultType.FAILURE)
+ throw new GradleException("Failed tests!")
+ }
}
}
-private static void printResults(allResults) {
- def maxLength = allResults*.readLines().flatten().collect { it.length() }.max()
+private static String colString(styler, col, colour, text) {
+ return col?"${styler[colour](text)}":text
+}
+
+private static String getSummaryLine(s, pn, tn, rt, rc, rs, rf, rsk, t, col) {
+ def colour = 'black'
+ def nocol = false
+ switch(rt) {
+ case TestResult.ResultType.SUCCESS:
+ colour = 'green'
+ break;
+ case TestResult.ResultType.FAILURE:
+ colour = 'red'
+ break;
+ default:
+ nocol = true
+ break;
+ }
+ StringBuilder sb = new StringBuilder()
+ sb.append("${pn}")
+ if (tn != null)
+ sb.append(":${tn}")
+ sb.append(" results: ")
+ sb.append(colString(s, col && !nocol, colour, rt))
+ sb.append(" (")
+ sb.append("${rc} tests, ")
+ sb.append(colString(s, col && rs > 0, 'green', rs))
+ sb.append(" successes, ")
+ sb.append(colString(s, col && rf > 0, 'red', rf))
+ sb.append(" failures, ")
+ sb.append("${rsk} skipped) in ${t}")
+ return sb.toString()
+}
- println "┌${"${"─" * maxLength}"}┐"
+private static void printResults(allResults) {
- println allResults.collect {
- it.readLines().collect {
- "│" + it + " " * (maxLength - it.length()) + "│"
- }.join("\n")
- }.join("\n├${"${"─" * maxLength}"}┤\n")
+ // styler from https://stackoverflow.com/a/56139852
+ def styler = 'black red green yellow blue magenta cyan white'.split().toList().withIndex(30).collectEntries { key, val -> [(key) : { "\033[${val}m${it}\033[0m" }] }
+
+ def maxLength = 0
+ def failedTests = false
+ def summaryLines = []
+ def totalcount = 0
+ def totalsuccess = 0
+ def totalfail = 0
+ def totalskip = 0
+ def totaltime = TimeCategory.getSeconds(0)
+ // sort on project name then task name
+ allResults.sort {a, b -> a[0] == b[0]? a[1]<=>b[1]:a[0] <=> b[0]}.each {
+ def projectName = it[0]
+ def taskName = it[1]
+ def result = it[2]
+ def time = it[3]
+ def report = it[4]
+ def summaryCol = getSummaryLine(styler, projectName, taskName, result.resultType, result.testCount, result.successfulTestCount, result.failedTestCount, result.skippedTestCount, time, true)
+ def summaryPlain = getSummaryLine(styler, projectName, taskName, result.resultType, result.testCount, result.successfulTestCount, result.failedTestCount, result.skippedTestCount, time, false)
+ def reportLine = "Report file: ${report}"
+ def ls = summaryPlain.length()
+ def lr = reportLine.length()
+ def m = [ls, lr].max()
+ if (m > maxLength)
+ maxLength = m
+ def info = [ls, summaryCol, reportLine]
+ summaryLines.add(info)
+ failedTests |= result.resultType == TestResult.ResultType.FAILURE
+ totalcount += result.testCount
+ totalsuccess += result.successfulTestCount
+ totalfail += result.failedTestCount
+ totalskip += result.skippedTestCount
+ totaltime += time
+ }
+ def totalSummaryCol = getSummaryLine(styler, "OVERALL", "", failedTests?TestResult.ResultType.FAILURE:TestResult.ResultType.SUCCESS, totalcount, totalsuccess, totalfail, totalskip, totaltime, true)
+ def totalSummaryPlain = getSummaryLine(styler, "OVERALL", "", failedTests?TestResult.ResultType.FAILURE:TestResult.ResultType.SUCCESS, totalcount, totalsuccess, totalfail, totalskip, totaltime, false)
+ def tls = totalSummaryPlain.length()
+ if (tls > maxLength)
+ maxLength = tls
+ def info = [tls, totalSummaryCol, null]
+ summaryLines.add(info)
+
+ def allSummaries = []
+ for(sInfo : summaryLines) {
+ def ls = sInfo[0]
+ def summary = sInfo[1]
+ def report = sInfo[2]
+
+ StringBuilder sb = new StringBuilder()
+ sb.append("│" + summary + " " * (maxLength - ls) + "│")
+ if (report != null) {
+ sb.append("\n│" + report + " " * (maxLength - report.length()) + "│")
+ }
+ allSummaries += sb.toString()
+ }
+ println "┌${"${"─" * maxLength}"}┐"
+ println allSummaries.join("\n├${"${"─" * maxLength}"}┤\n")
println "└${"${"─" * maxLength}"}┘"
}
/* END of test tasks results summary */
-task verifyTestStatus {
- group = "Verification"
- description = "Task that FAILs the build if any tests failed"
- doLast {
- if (testsFailed) {
- throw new GradleException("There were failing tests!")
- }
- }
-}
-
test {
// from original test task
if (useClover) {
dependsOn testClasses
}
dependsOn tasks.withType(Test).matching {t -> t.getName().startsWith("testTask")}
- finalizedBy verifyTestStatus
-
// not running tests in this task
exclude "**/*"