From a34b7ee4b79b3e4dae29098297bd946f3a9e4fe1 Mon Sep 17 00:00:00 2001 From: "Johnny Miller (ZA)" Date: Fri, 12 Aug 2022 14:44:44 +0800 Subject: [PATCH] perf($Gradle): execute unit tests in parallel mode; supports JaCoCo https://www.jvt.me/posts/2021/03/11/gradle-speed-parallel/ --- build.gradle.kts | 55 ++++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 48 insertions(+), 7 deletions(-) diff --git a/build.gradle.kts b/build.gradle.kts index d1f7cc91..8ffa7806 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,8 +1,10 @@ import enforcer.rules.RequireGradleVersion -import enforcer.rules.RequireJavaVersion import enforcer.rules.RequireJavaVendor +import enforcer.rules.RequireJavaVersion import io.spring.gradle.dependencymanagement.dsl.DependencyManagementExtension import org.gradle.api.JavaVersion.VERSION_17 +import org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL +import org.gradle.api.tasks.testing.logging.TestLogEvent.* import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.springframework.boot.gradle.tasks.bundling.BootJar @@ -10,6 +12,7 @@ plugins { java idea `java-library` + jacoco `maven-publish` kotlin("jvm") kotlin("kapt") @@ -66,6 +69,7 @@ subprojects { apply { plugin("java") plugin("java-library") + plugin("jacoco") plugin("kotlin") plugin("kotlin-kapt") plugin("org.jetbrains.kotlin.plugin.spring") @@ -90,18 +94,56 @@ subprojects { options.isFork = true } - tasks.withType { - useJUnitPlatform() - } - // https://docs.gradle.org/current/userguide/performance.html#parallel_test_execution tasks.withType().configureEach { - // The normal approach is to use some number less than or equal to the number of CPU cores you have, such as this algorithm: + // The normal approach is to use some number less than or equal to the number of CPU cores you have, + // such as this algorithm: maxParallelForks = (Runtime.getRuntime().availableProcessors() / 2).takeIf { it > 0 } ?: 1 // To fork a new test VM after a certain number of tests have run setForkEvery(100) } + // https://docs.gradle.org/current/dsl/org.gradle.api.tasks.testing.Test.html + tasks.withType { + // Configuration parameters to execute top-level classes in parallel but methods in the same thread + // https://www.jvt.me/posts/2021/03/11/gradle-speed-parallel/ + systemProperties["junit.jupiter.execution.parallel.enabled"] = "true" + systemProperties["junit.jupiter.execution.parallel.mode.default"] = "concurrent" + systemProperties["junit.jupiter.execution.parallel.mode.classes.default"] = "concurrent" + // Discover and execute JUnit Platform-based tests + useJUnitPlatform() + failFast = true + // https://technology.lastminute.com/junit5-kotlin-and-gradle-dsl/ + testLogging { + // set options for log level LIFECYCLE + events = mutableSetOf(FAILED, PASSED, SKIPPED, STANDARD_OUT) + exceptionFormat = FULL + showStandardStreams = true + showExceptions = true + showCauses = true + showStackTraces = true + // set options for log level DEBUG and INFO + debug { + events = mutableSetOf(FAILED, PASSED, SKIPPED, STANDARD_OUT) + exceptionFormat = FULL + } + info { + events = debug.events + exceptionFormat = debug.exceptionFormat + } + } + // report is always generated after tests run + finalizedBy(tasks.jacocoTestReport) + } + + tasks.jacocoTestReport { + // tests are required to run before generating the report + dependsOn(tasks.test) + reports { + csv.required.set(true) + } + } + // Disable for take of building Spring Boot executable jar for most of the subprojects, // Only bootstrap subproject needs it to be `true`. tasks.withType { @@ -148,7 +190,6 @@ subprojects { // Testing testImplementation("org.springframework.boot:spring-boot-starter-test") testImplementation("org.mockito.kotlin:mockito-kotlin:$mockitoKotlinVersion") - testImplementation("org.jacoco:org.jacoco.agent:0.8.8") } configurations {