gradle
gradle copied to clipboard
jvm-test-suite - support depencency bundles
Expected Behavior
I assumed that this setup would work:
libs.versions.toml
[libraries]
spring-test = { module = "org.springframework.boot:spring-boot-starter-test" }
junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api" }
junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine" }
[bundles]
spring-test = ["spring-test", "junit-jupiter-api", "junit-jupiter-engine"]
build.gradle.kts
testing {
suites {
register<JvmTestSuite>("integrationTest") {
useJUnitJupiter()
dependencies {
implementation(libs.bundles.spring.test)
}
}
}
}
Current Behavior (optional)
It seems like you'll have to include all depenencies individually like:
libs.versions.toml
[libraries]
spring-test = { module = "org.springframework.boot:spring-boot-starter-test" }
junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api" }
junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine" }
build.gradle.kts
testing {
suites {
register<JvmTestSuite>("integrationTest") {
useJUnitJupiter()
dependencies {
implementation(libs.spring.test)
implementation(libs.junit.jupiter.api)
implementation(libs.junit.jupiter.engine)
}
}
}
}
Context
In a multi-project build there are multiple benefits with declaring dependency versions centrally and to be able to bundle them is a great way of streamlining the project configurations. I've managed to do a workaround by extending the testImplementation configuration, but as far as I know, it's an anti pattern to use config.extendsFrom? Am I missing something obvious?
Solution
libs.versions.toml
[libraries]
spring-test = { module = "org.springframework.boot:spring-boot-starter-test" }
junit-jupiter-api = { module = "org.junit.jupiter:junit-jupiter-api" }
junit-jupiter-engine = { module = "org.junit.jupiter:junit-jupiter-engine" }
[bundles]
spring-test-bundle = ["spring-test", "junit-jupiter-api", "junit-jupiter-engine"]
build.gradle.kts
testing {
suites {
register<JvmTestSuite>("integrationTest") {
useJUnitJupiter()
dependencies {
implementation(libs.bundles.spring.test.bundle.get())
}
}
}
}
What's Happening?
- Bundle Defined: You create a
spring-test-bundleinlibs.versions.toml. - Bundle Applied: In your
build.gradle.kts, you apply that bundle to yourintegrationTestsuite.
This approach keeps your dependencies centralized and clean. If you prefer, you can extend testImplementation, but using bundles like this is generally more maintainable.
@Kaos2121 Thanks! I am getting the following error though:
@Kaos2121 Thanks! I am getting the following error though:
1. Bundle Name: Ensure libs.bundles.spring.test.bundle.get() matches exactly with what’s in libs.versions.toml.
2. Remove .get(): Try using implementation(libs.bundles.spring.test.bundle) without .get().
3. Verify References: Double-check that all dependencies are correctly referenced and resolve properly.
Check these
1. Bundle Name: Ensure libs.bundles.spring.test.bundle.get() matches exactly with what’s in libs.versions.toml. 2. Remove .get(): Try using implementation(libs.bundles.spring.test.bundle) without .get(). 3. Verify References: Double-check that all dependencies are correctly referenced and resolve properly.Check these
The reference seems correct (I'm able to follow the reference in the IDE). Without .get(), the error logs hint that a list of references is unsupported:
Cannot convert the provided notation to an object of type Dependency: org.gradle.accessors.dm.LibrariesForLibs$SpringTestBundleAccessors@74078d7a.
The following types/formats are supported:
- String or CharSequence values, for example 'org.gradle:gradle-core:1.0'.
- Maps, for example [group: 'org.gradle', name: 'gradle-core', version: '1.0'].
- FileCollections, for example files('some.jar', 'someOther.jar').
- Projects, for example project(':some:project:path').
- ClassPathNotation, for example gradleApi().
The issue is in the backlog of the relevant team and is prioritized by them.
This is a known limitation
You cannot add version catalog bundles directly. Instead, use the bundle method on each configuration. Kotlin and Groovy: implementation(libs.bundles.testing) becomes implementation.bundle(libs.bundles.testing)
However, at least our docs should be updated to reference these differences here.
And the error should be more clear. It might be hard to fix since it's a compilation error, but from a user perspective, it's something we should address.
The issue is in the backlog of the relevant team and is prioritized by them.
This is a known limitation
You cannot add version catalog bundles directly. Instead, use the bundle method on each configuration. Kotlin and Groovy: implementation(libs.bundles.testing) becomes implementation.bundle(libs.bundles.testing)
However, at least our docs should be updated to reference these differences here.
And the error should be more clear. It might be hard to fix since it's a compilation error, but from a user perspective, it's something we should address.
Thanks! implementation.bundle is a "good enough" solution for me but it would indeed be great with updated docs.
Thinking some more about this, I wonder if we should not update the root dependencies block so that it behaves the same:
- Add a
bundlemethod onConfigurationto pass in a version catalog bundle - Deprecate passing a bundle directly
- Remove on next major
Maybe the whole "traditional" dependencies block should be redone to use the new API you also use in jvm test suites block and so on to gain full equality also for future changes, not only adjusting the bundle usage.
