Skip to content

Commit

Permalink
Lazy configuration
Browse files Browse the repository at this point in the history
  • Loading branch information
pmendelski committed Nov 26, 2024
1 parent 1b7f646 commit ae969cc
Show file tree
Hide file tree
Showing 16 changed files with 104 additions and 72 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@
and [Kover](https://github.com/Kotlin/kotlinx-kover).
- Integrates with test frameworks like [JUnit5](https://junit.org/junit5/), [Spock](https://spockframework.org/) and
[Kotest](https://kotest.io/).
- Compatible with [gradle configuration cache](https://docs.gradle.org/current/userguide/configuration_cache.html).
- Compatible with [gradle configuration cache](https://docs.gradle.org/current/userguide/configuration_cache.html)
and [lazy task configuration](https://docs.gradle.org/current/userguide/lazy_configuration.html).

## Using the plugin

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ class CommandLineTest {
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${Versions.junit}")
}
tasks.withType<Test> {
tasks.withType<Test>().configureEach {
useJUnitPlatform()
testLogging {
events("passed", "failed", "skipped")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ class JUnitBasicTest {
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${Versions.junit}")
}
tasks.withType<Test> {
tasks.withType<Test>().configureEach {
useJUnitPlatform()
testLogging {
events("passed", "failed", "skipped")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class JUnitClasspathTest {
integrationImplementation("com.google.code.gson:gson:${Versions.gson}")
}
tasks.withType<Test> {
tasks.withType<Test>().configureEach {
useJUnitPlatform()
testLogging {
events("passed", "failed", "skipped")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class JacocoBasedTest {
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${Versions.junit}")
}
tasks.withType<Test> {
tasks.withType<Test>().configureEach {
useJUnitPlatform()
testLogging {
events("passed", "failed", "skipped")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ class KotestBasicTest {
testImplementation("io.kotest:kotest-runner-junit5:${Versions.kotest}")
}
tasks.withType<Test> {
tasks.withType<Test>().configureEach {
useJUnitPlatform()
testLogging {
events("passed", "failed", "skipped")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ class KotestClasspathTest {
integrationImplementation("com.google.code.gson:gson:${Versions.gson}")
}
tasks.withType<Test> {
tasks.withType<Test>().configureEach {
useJUnitPlatform()
testLogging {
events("passed", "failed", "skipped")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class KotlinInternalScopeTest {
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${Versions.junit}")
}
tasks.withType<Test> {
tasks.withType<Test>().configureEach {
useJUnitPlatform()
testLogging {
events("passed", "failed", "skipped")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package com.coditory.gradle.integration

import com.coditory.gradle.integration.base.TestProjectBuilder
import org.assertj.core.api.Assertions.assertThat
import org.junit.jupiter.api.AutoClose
import org.junit.jupiter.api.Test

class LazyTaskRegisteringTest {
companion object {
const val TEST_CONFIG_LOG = "Long running configuration..."

@AutoClose
private val project = TestProjectBuilder
.project(LazyTaskRegisteringTest::class.simpleName!!)
.withBuildGradleKts(
"""
plugins {
id("jacoco")
id("com.coditory.integration-test")
}
repositories {
mavenCentral()
}
dependencies {
testImplementation("org.junit.jupiter:junit-jupiter-api:${Versions.junit}")
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${Versions.junit}")
}
tasks.withType<Test>().configureEach {
println("$TEST_CONFIG_LOG")
}
""",
)
.build()
}

@Test
fun `should register test tasks in a lazy manner`() {
// when
val result = project.runGradle(listOf("clean"))
// then
assertThat(result.output).doesNotContain(TEST_CONFIG_LOG)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ class LombokTest {
testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:${Versions.junit}")
}
tasks.withType<Test> {
tasks.withType<Test>().configureEach {
useJUnitPlatform()
testLogging {
events("passed", "failed", "skipped")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ class PlatformDependencyTest {
integrationImplementation("org.springframework.boot:spring-boot-starter-test")
}
tasks.withType<Test> {
tasks.withType<Test>().configureEach {
useJUnitPlatform()
testLogging {
events("passed", "failed", "skipped")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,20 +8,27 @@ import org.gradle.testing.jacoco.tasks.JacocoReport

internal object JacocoTaskConfiguration {
fun apply(project: Project) {
if (project.pluginManager.hasPlugin("jacoco")) {
var dstFile: String? = null
project.tasks.named(INTEGRATION) { task ->
val jacocoTaskExtension = task.extensions.getByType(JacocoTaskExtension::class.java)
dstFile = jacocoTaskExtension.destinationFile?.path
}
if (dstFile != null) {
project.tasks.withType(JacocoReport::class.java) { task ->
task.executionData(dstFile)
task.mustRunAfter(INTEGRATION)
}
project.tasks.withType(JacocoCoverageVerification::class.java) { task ->
task.mustRunAfter(INTEGRATION)
}
if (!project.pluginManager.hasPlugin("jacoco")) return
project.tasks.withType(JacocoCoverageVerification::class.java).configureEach { task ->
task.mustRunAfter(INTEGRATION)
}
project.tasks.withType(JacocoReport::class.java).configureEach { task ->
task.mustRunAfter(INTEGRATION)
}
// execute only if integration test and jacoco are on the execution path
// to preserve lazy task configuration
project.gradle.taskGraph.whenReady {
val names = project.gradle.taskGraph.allTasks.map { it.name }
if (names.contains("jacocoTestReport") && names.contains(INTEGRATION)) {
project.tasks.withType(JacocoReport::class.java)
.named("jacocoTestReport") { reportTask ->
val jacocoTaskExtension =
project.tasks.getByName(INTEGRATION).extensions.getByType(JacocoTaskExtension::class.java)
val dstFile = jacocoTaskExtension.destinationFile?.path
if (dstFile != null) {
reportTask.executionData(dstFile)
}
}
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,20 @@ package com.coditory.gradle.integration
import com.coditory.gradle.integration.IntegrationTestPlugin.Companion.INTEGRATION_TEST
import com.coditory.gradle.integration.IntegrationTestPlugin.Companion.TEST_ALL_TASK_NAME
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.tasks.testing.Test
import org.gradle.language.base.plugins.LifecycleBasePlugin

internal object TestAllTaskConfiguration {
fun apply(project: Project, config: IntegrationTestPluginConfig) {
val testAllTask = project.tasks.create(TEST_ALL_TASK_NAME)
testAllTask.description = "Runs all test suites."
testAllTask.group = LifecycleBasePlugin.VERIFICATION_GROUP
testAllTask.enabled = config.allTestTaskEnabled
project.tasks.withType(Test::class.java).forEach {
testAllTask.dependsOn(it.name)
project.tasks.register(TEST_ALL_TASK_NAME) { testAllTask: Task ->
testAllTask.description = "Runs all test suites."
testAllTask.group = LifecycleBasePlugin.VERIFICATION_GROUP
testAllTask.enabled = config.allTestTaskEnabled
project.tasks.withType(Test::class.java).names.forEach {
testAllTask.dependsOn(it)
}
testAllTask.dependsOn(INTEGRATION_TEST)
}
testAllTask.dependsOn(INTEGRATION_TEST)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.coditory.gradle.integration
import com.coditory.gradle.integration.IntegrationTestPlugin.Companion.INTEGRATION
import com.coditory.gradle.integration.IntegrationTestPlugin.Companion.INTEGRATION_TEST
import org.gradle.api.Project
import org.gradle.api.Task
import org.gradle.api.attributes.TestSuiteType
import org.gradle.api.plugins.JavaBasePlugin
import org.gradle.api.plugins.JavaPluginExtension
Expand Down Expand Up @@ -70,17 +71,19 @@ internal object TestSuitesConfiguration {
}

private fun setupTestTask(project: Project, config: IntegrationTestPluginConfig) {
val integrationTestTask = project.tasks.create(INTEGRATION_TEST)
integrationTestTask.description = "Runs integration test suites."
integrationTestTask.group = LifecycleBasePlugin.VERIFICATION_GROUP
integrationTestTask.enabled = config.integrationTestsEnabled
integrationTestTask.dependsOn(INTEGRATION)
project.tasks.getByName(JavaBasePlugin.CHECK_TASK_NAME)
.dependsOn(INTEGRATION_TEST)
project.tasks.getByName(JavaBasePlugin.CHECK_TASK_NAME)
.dependsOn(INTEGRATION)
project.tasks.getByName(INTEGRATION)
.enabled = config.integrationTestsEnabled
project.tasks.register(INTEGRATION_TEST) { integrationTestTask: Task ->
integrationTestTask.description = "Runs integration test suites."
integrationTestTask.group = LifecycleBasePlugin.VERIFICATION_GROUP
integrationTestTask.enabled = config.integrationTestsEnabled
integrationTestTask.dependsOn(INTEGRATION)
}
project.tasks.named(JavaBasePlugin.CHECK_TASK_NAME) { checkTask ->
checkTask.dependsOn(INTEGRATION_TEST)
checkTask.dependsOn(INTEGRATION)
}
project.tasks.named(INTEGRATION) { integrationTask ->
integrationTask.enabled = config.integrationTestsEnabled
}
}

private fun configureKotlinCompilation(project: Project) {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -30,10 +30,11 @@ class TestProject(private val project: Project) : Project by project {
}

private fun gradleRunner(project: Project, arguments: List<String>, gradleVersion: String? = null): GradleRunner {
// clean is required so tasks are not cached
val args = if (arguments.contains("clean")) arguments else listOf("clean") + arguments
val builder = GradleRunner.create()
.withProjectDir(project.projectDir)
// clean is required so tasks are not cached
.withArguments(listOf("clean") + arguments)
.withArguments(args)
.withPluginClasspath()
.forwardOutput()
if (!gradleVersion.isNullOrBlank() && gradleVersion != "current") {
Expand Down

0 comments on commit ae969cc

Please sign in to comment.