简体   繁体   中英

How to access tests jar in gradle in multi-module project

I have multimodule project. From one of the modules I need to refer the test classes from other module. I tried to configure like this:

// core project
val testJar by tasks.registering(Jar::class) {
    archiveClassifier.set("tests")
    from(project.the<SourceSetContainer>()["test"].output)
}
val testArtifact by configurations.creating
artifacts.add(testArtifact.name, testJar)

And I'm trying to refer to that configuration from other project:

dependencies {
    // other dependencies ommited
    api(project(":core"))
    testImplementation(project(path = ":core", configuration = "testArtifact"))
}

But this configuration doesn't work. The compilation of other project is failing as it doesn't see the required tests classes from core project. The dependency insight:

./gradlew :service:dependencyInsight --dependency core --configuration testCompileClasspath

It gives following:

project :core
  variant "apiElements" [
    org.gradle.usage = java-api
  ]
  variant "testArtifact" [
    Requested attributes not found in the selected variant:
      org.gradle.usage = java-api
  ]

I'm struggling to understand how to make configuration to work so that I can compile the service project's test classes. Running on Gradle 5.2.1 with Kotlin DSL.

So what is described above works on the command line but not in the IDE.

Here is a variation, that builds on the variant-aware dependency management:

plugins {
    `java-library`
}

repositories {
    mavenCentral()
}

group = "org.test"
version = "1.0"

val testJar by tasks.registering(Jar::class) {
    archiveClassifier.set("tests")
    from(project.the<SourceSetContainer>()["test"].output)
}

// Create a configuration for runtime
val testRuntimeElements by configurations.creating {
    isCanBeConsumed = true
    isCanBeResolved = false
    attributes {
        attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class, Usage.JAVA_RUNTIME_JARS))
    }
    outgoing {
        // Indicate a different capability (defaults to group:name:version)
        capability("org.test:lib-test:$version")
    }
}

// Second configuration declaration, this is because of the API vs runtime difference Gradle makes and rules around valid multiple variant selection
val testApiElements by configurations.creating {
    isCanBeConsumed = true
    isCanBeResolved = false
    attributes {
        // API instead of runtime usage
        attribute(Usage.USAGE_ATTRIBUTE, project.objects.named(Usage::class, Usage.JAVA_API_JARS))
    }
    outgoing {
        // Same capability
        capability("org.test:lib-test:$version")
    }
}

artifacts.add(testRuntimeElements.name, testJar)
artifacts.add(testApiElements.name, testJar)

Because of the variant-aware dependency management rules, the above looks like a lot. But if it was extracted in a plugin, most of this could be factored out.

And on the consumer side:

testImplementation(project(":lib")) {
    capabilities {
        // Indicate we want a variant with a specific capability
        requireCapability("org.test:lib-test")
    }
}

Note that this requires Gradle 5.3.1. The import of the project in IntelliJ 2019.1 properly wires up the dependencies and test code can compile in the IDE.

Which IDE ? It works for me both in terminal and IDE : I use IntelliJ (2019.3) and Gradle (6.0.1, not Kotlin DSL)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM