Search code examples
gradle-kotlin-dsljava-test-fixtures

Understanding the publication and implementation of test fixtures


For context, what I am trying to achieve being able to use test fixtures cross projects.

Within projects in the same repo, this is no issue and works as expected. However, as an external dependency I struggle to make it work.

First of all, when I am publishing the artifacts I get the following warning/error:

Maven publication 'baz' pom metadata warnings (silence with 'suppressPomMetadataWarningsFor(variant)'):
  - Variant testFixturesApiElements:
      - Declares capability foo.bar:baz-test-fixtures:1.2.3-SNAPSHOT which cannot be mapped to Maven
  - Variant testFixturesRuntimeElements:
      - Declares capability foo.bar:baz-test-fixtures:1.2.3-SNAPSHOT which cannot be mapped to Maven
These issues indicate information that is lost in the published 'pom' metadata file, which may be an issue if the published library is consumed by an old Gradle version or Apache Maven.
The 'module' metadata file, which is used by Gradle 6+ is not affected.

Dispite this, the artifact is published but the classifier (test-fixtures) is applied after the version foo.bar:baz-1.2.3-SNAPSHOT-test-fixtures.jar. Is this actually intended? I would expect the version to be the last part. Please correct me if I am wrong here. According to https://developer.android.com/studio/publish-library/configure-test-fixtures it does seem to me as if it should produce what I expect assuming groupId, artifactId and version is defined, which they are (see Publishing test fixtures with submodules, gradle for my setup).

Assuming what I described above is actually correct, I am unable to actually introduce the jar as a dependency automatically. I have tried to add the jar to the classpath manually which works fine as expected. This is what I have tried:

testImplementation(testFixtures("foo.bar:baz:1.2.3-SNAPSHOT")) testImplementation(testFixtures("foo.bar:baz:1.2.3-SNAPSHOT-test-fixtures"))

I have tried renaming the jar file itself, but this does not work either.

Going back to the issue during publication. Is there something I have missed to ensure this capability of my artifact perhaps?

EDIT:

// Build.gradle.kts in baz submodule
plugins {
    id("java-library")
    id("java-test-fixtures")
}

dependencies {
    testFixturesApi(project(":baz"))
}
import org.springframework.boot.gradle.tasks.bundling.BootJar

// values, ie val javaVersion: String by project.

allprojects {
    group = "${projectGroup}.${rootProject.name}"
    version = projectVersion
}

repositories {
    mavenCentral()
    mavenLocal()
}

plugins {
    id("org.springframework.boot") version "2.6.1" apply false
    id("io.spring.dependency-management") version "1.0.11.RELEASE" apply false
    kotlin("jvm") version "1.6.0"
    kotlin("plugin.spring") version "1.6.0"
    id("maven-publish")
}

tasks {
    withType<JavaCompile> {
        sourceCompatibility = javaVersion
        targetCompatibility = javaVersion
    }

    withType<KotlinCompile> {
        kotlinOptions {
            freeCompilerArgs = listOf("-Xjsr305=strict")
            jvmTarget = javaVersion
        }
    }

    withType<Test> {
        useJUnitPlatform()
    }

    withType<Wrapper> {
        gradleVersion = "7.3"
    }

    withType<BootJar> {
        enabled = false
    }
}

subprojects {
    repositories {
        mavenCentral()
        mavenLocal()
    }

    apply {
        plugin("io.spring.dependency-management")
        plugin("org.springframework.boot")
        plugin("org.jetbrains.kotlin.jvm")
        plugin("org.jetbrains.kotlin.plugin.spring")
        plugin("org.jetbrains.kotlin.plugin.jpa")
        plugin("maven-publish")
    }

    tasks {
        register("prepareKotlinBuildScriptModel") {}

        withType<BootJar> {
            enabled = false
        }

        withType<Test> {
            useJUnitPlatform()
        }

        getByName<Jar>("jar") {
            enabled = true
        }

    }

    publishing {
        publications {
            create<MavenPublication>(project.name) {
                artifactId = "${shortName}-${tasks.jar.get().archiveBaseName.get()}"

                val javaComponent = 
                from(components["java"])
            }
        }
    }
}

Other than the output I included above, these are the tasks that are done:

> Task :baz:compileTestFixturesKotlin
> Task :baz:compileTestFixturesJava NO-SOURCE
> Task :baz:processTestFixturesResources NO-SOURCE
> Task :baz:testFixturesClasses UP-TO-DATE
> Task :baz:testFixturesJar
> Task :baz:generateMetadataFileForBazPublication
> Task :baz:generatePomFileForBazPublication
> Task :baz:publishBazPublicationToMavenLocal
> Task :baz:publishToMavenLocal

EDIT 2:

This is also in maven-metadata-local.xml

<snapshotVersion>
 <classifier>test-fixtures</classifier>
 <extension>jar</extension>
 <value>1.2.3-SNAPSHOT</value>
 <updated>20230213100621</updated>
</snapshotVersion>

Solution

  • This was solved by adding the classifier test-fixtures to the implementation statement as such:

    testImplementation("foo.bar:baz:1.2.3-SNAPSHOT:test-fixtures")

    I am still a bit puzzled as to why testImplementation("foo.bar:baz:1.2.3-SNAPSHOT") does not work, but this will do.