I have a Compose multiplatform project that looks like this

I have a set of tests in desktopTest, as intended. But I'd also like to have a set of tests that I run only when desired, when preparing for a release for example.
For this, I am trying to create an additional module (called desktopFullChainTest here).
I am struggling to find the build.gradle.kts configuration that will mirror the behavior of desktopTest (contains own set of dependencies, also includes desktopMain sources, includes desktopMain dependencies too).
I have a minimal reproduceable example here.
To reproduce :
- Run
./gradlew desktopTest# All tests run successfully - Run
./gradlew desktopChainTestTest fails with aNoClassDefFoundError
What I've done :
I have originally modified the gradle file as such, to follow the documentation :
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.composeCompiler)
}
kotlin {
jvm("desktop")
sourceSets {
val desktopMain by getting
val desktopTest by getting
val desktopFullChainTest by creating {
dependsOn(desktopTest)
}
commonMain.dependencies {
implementation(compose.runtime)
implementation(compose.foundation)
implementation(compose.material)
implementation(compose.ui)
implementation(compose.components.resources)
implementation(compose.components.uiToolingPreview)
implementation(libs.androidx.lifecycle.viewmodel)
implementation(libs.androidx.lifecycle.runtime.compose)
implementation(libs.ktor.client.core)
implementation(libs.ktor.client.java)
implementation(libs.ktor.client.logging)
implementation(libs.ktor.client.logging.logback)
implementation(libs.kbsky.core)
}
desktopMain.dependencies {
implementation(compose.desktop.currentOs)
implementation(libs.kotlinx.coroutines.swing)
}
desktopTest.dependencies {
implementation(kotlin("test"))
implementation(libs.junit5)
}
desktopFullChainTest.dependencies {
implementation(kotlin("test"))
implementation(libs.junit5)
}
tasks.withType<Test> {
useJUnitPlatform()
}
}
}
compose.desktop {
application {
mainClass = "nl.lengrand.MainKt"
nativeDistributions {
targetFormats(TargetFormat.Dmg, TargetFormat.Msi, TargetFormat.Deb)
packageName = "nl.lengrand"
packageVersion = "1.0.0"
}
}
}
but neither my IDE nor gradle recognize the declared dependencies
Junie has offered to specifically mention source sets :
import org.jetbrains.compose.desktop.application.dsl.TargetFormat
plugins {
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.composeMultiplatform)
alias(libs.plugins.composeCompiler)
}
kotlin {
jvm("desktop")
sourceSets {
val desktopMain by getting
val desktopTest by getting
val desktopFullChainTest by creating {
kotlin.srcDir("src/desktopFullChainTest/kotlin")
resources.srcDir("src/desktopFullChainTest/resources")
}
afterEvaluate {
val desktopMainCompilation = kotlin.targets.getByName("desktop").compilations.getByName("main")
val desktopFullChainTestCompilation = kotlin.targets.getByName("desktop").compilations.create("fullChainTest")
desktopFullChainTestCompilation.defaultSourceSet.dependsOn(desktopFullChainTest)
desktopFullChainTestCompilation.associateWith(desktopMainCompilation)
}
...
desktopFullChainTest.dependencies {
implementation(kotlin("test"))
implementation(libs.junit5)
}
...
}
}
afterEvaluate {
tasks.register<Test>("desktopFullChainTest") {
description = "Runs full chain tests"
val fullChainTestCompilation = kotlin.targets.getByName("desktop").compilations.getByName("fullChainTest")
testClassesDirs = fullChainTestCompilation.output.classesDirs
classpath = fullChainTestCompilation.output.classesDirs +
fullChainTestCompilation.compileDependencyFiles +
fullChainTestCompilation.output.resourcesDir.let { if (it.exists()) files(it) else files() }
useJUnitPlatform()
}
}
....
This fixes the import issues indeed, as well as the main module code imports, but all transitive dependencies from main aren't included either :
java.lang.NoClassDefFoundError: kotlinx/serialization/json/JsonBuilder
at work.socialhub.kbsky.internal.share._InternalUtility.<clinit>(_InternalUtility.kt:24)
at work.socialhub.kbsky.internal.com.atproto._ServerResource.createSession(_ServerResource.kt:43)
at nl.lengrand.posters.DefaultBlueskyAPI.createSession(DefaultBlueskyAPI.kt:22)
This is not really surprising, since we are statically declaring a lot of locations, but I also fail to see a clearer way to do things in the docs.
Could someone please hint me at a valid configuration?
