diff --git a/app/build.gradle.kts b/app/build.gradle.kts index feae9e1..d9af619 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -3,6 +3,10 @@ plugins { id("kotlin-android") } +apply { + from(file("$rootDir/gradle_tests_report.gradle.kts")) +} + android { compileSdk = 30 buildToolsVersion = "30.0.3" diff --git a/data/build.gradle b/data/build.gradle index cf44b36..b744ea1 100644 --- a/data/build.gradle +++ b/data/build.gradle @@ -3,6 +3,10 @@ plugins { id("kotlin") } +apply { + from(file("$rootDir/gradle_tests_report.gradle.kts")) +} + java { sourceCompatibility = JavaVersion.VERSION_1_7 targetCompatibility = JavaVersion.VERSION_1_7 diff --git a/device/build.gradle b/device/build.gradle index d7dcf24..19bc0cd 100644 --- a/device/build.gradle +++ b/device/build.gradle @@ -3,6 +3,9 @@ plugins { id 'kotlin-android' id 'kotlin-kapt' } +apply { + from(file("$rootDir/gradle_tests_report.gradle.kts")) +} android { compileSdk 30 diff --git a/domain/build.gradle b/domain/build.gradle index 2f7915b..ed05b38 100644 --- a/domain/build.gradle +++ b/domain/build.gradle @@ -2,6 +2,9 @@ plugins { id 'java-library' id 'kotlin' } +apply { + from(file("$rootDir/gradle_tests_report.gradle.kts")) +} java { sourceCompatibility = JavaVersion.VERSION_1_7 diff --git a/gradle_tests_report.gradle.kts b/gradle_tests_report.gradle.kts new file mode 100644 index 0000000..055d3d4 --- /dev/null +++ b/gradle_tests_report.gradle.kts @@ -0,0 +1,91 @@ +import org.gradle.api.tasks.testing.logging.TestExceptionFormat +import org.gradle.api.tasks.testing.logging.TestLogEvent +import groovy.time.TimeCategory +import java.util.Date + +/** + * based on the groovy code by lwasyl: + * https://gist.github.com/lwasyl/f5b2b4ebe9e348ebbd8ee4cb995f8362 + * https://medium.com/@wasyl/pretty-tests-summary-in-gradle-744804dd676c + */ +var testResults by extra(mutableListOf()) // Container for tests summaries + +tasks.withType().configureEach { + val testTask = this + + testLogging { + events = setOf( + TestLogEvent.FAILED, + TestLogEvent.SKIPPED, + TestLogEvent.STANDARD_OUT, + TestLogEvent.STANDARD_ERROR + ) + + exceptionFormat = TestExceptionFormat.FULL + showExceptions = true + showCauses = true + showStackTraces = true + } + + ignoreFailures = true // Always try to run all tests for all modules + + //addTestListener is a workaround https://github.com/gradle/kotlin-dsl-samples/issues/836 + addTestListener(object : TestListener { + override fun beforeSuite(suite: TestDescriptor) {} + override fun beforeTest(testDescriptor: TestDescriptor) {} + override fun afterTest(testDescriptor: TestDescriptor, result: TestResult) {} + override fun afterSuite(desc: TestDescriptor, result: TestResult) { + if (desc.parent != null) return // Only summarize results for whole modules + + val summary = TestOutcome().apply { + add( "${testTask.project.name}:${testTask.name} results: ${result.resultType} " + + "(" + + "${result.testCount} tests, " + + "${result.successfulTestCount} successes, " + + "${result.failedTestCount} failures, " + + "${result.skippedTestCount} skipped" + + ") " + + "in ${TimeCategory.minus(Date(result.endTime), Date(result.startTime))}") + add("Report file: ${testTask.reports.html.entryPoint}") + } + + // Add reports in `testsResults`, keep failed suites at the end + if (result.resultType == TestResult.ResultType.SUCCESS) { + testResults.add(0, summary) + } else { + testResults.add(summary) + } + } + }) +} + +gradle.buildFinished { + if (testResults.isNotEmpty()) { + printResults(testResults) + } +} + +fun printResults(allResults:List) { + val maxLength = allResults.map{ it.maxWidth() } + .maxOrNull() ?: 0 + + println("┌${"─".repeat(maxLength)}┐") + + println(allResults.joinToString("├${"─".repeat(maxLength)}┤\n") { testOutcome -> + testOutcome.lines.joinToString("│\n│", "│", "│") { + it + " ".repeat(maxLength - it.length) + } + }) + + println("└${"─".repeat(maxLength)}┘") +} + +data class TestOutcome(val lines:MutableList = mutableListOf()) { + fun add(line:String) { + lines.add(line) + } + + fun maxWidth(): Int { + return lines.maxByOrNull { it.length }?.length ?: 0 + } +}