Integration Test Not Pulling in Project dependency


(Ed Mitchell) #1

Gradle 4.7

I’m currently running into an issue when following the guide here on how to create an integration test configuration/task:

https://docs.gradle.org/current/userguide/java_testing.html#sec:configuring_java_integration_tests

sourceSets {
    "integration-test" {
        compileClasspath += main.output + test.output + configurations.testRuntime
        runtimeClasspath += output + compileClasspath
    }
}

configurations {
    integrationTestImplementation.extendsFrom implementation
    integrationTestImplementation.extendsFrom testImplementation
}

task integrationTest(type: Test) {
    testClassesDirs = sourceSets."integration-test".output.classesDirs
    classpath = sourceSets."integration-test".runtimeClasspath
}

dependencies {
    implementation project(":client")
}

Whenever I run ./gradlew build integrationTest, the tests fail to compile missing classes defined in the client project. Whenever I run ./gradlew integrationTest, the tests compile properly, and pass.

I’m at my wits end trying to figure out why this is failing. The project is in the integrationTestCompileClasspath dependency, so I don’t see why it would be unable to reference those classes.

Thanks!


(Ed Mitchell) #2

For the purposes of posterity, I figured out what the issue was.

Part of the work I’m doing here is developing a plugin for a conventional project structure for our microservices. The structure is as followed:

root -> service-client
        service

service-client’s build.gradle file looks like this:

publishing {
    publications {
        serviceClient(MavenPublication){
            artifactId artifactId
            from components.java
            artifact sourcesJar{
                classifier "sources"
            }
        }
    }
}

task sourcesJar(type: Jar, dependsOn: classes){
    from sourceSets.main.allSource
}

artifacts{
    archives sourcesJar
}

which would match the following Plugin Code (or so I thought)

val sourceSet = convention.getPlugin(JavaPluginConvention::class.java).sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME)

val task = tasks.create("sourcesJar", Jar::class.java, {
    it.dependsOn.add("classes")
    it.from(sourceSet.allSource)
})

artifacts.add("archives", task)
extensions.configure(PublishingExtension::class.java, {
    it.publications.create(CaseFormat.LOWER_HYPHEN.to(CaseFormat.LOWER_CAMEL, name), MavenPublication::class.java, {
        it.from(components.getByName("java"))
        it.artifact(task, {
            it.classifier = "sources"
        })
    })
})

However, every time I run ./gradlew build integrationTest, the build fails with being unable to access the classes in the service-client project. If I do just ./gradlew integrationTest it works.

If I change the classifier declaration from being within the artifact block and put it on the Jar task instead, then everything starts working. My new code:

val sourceSet = convention.getPlugin(JavaPluginConvention::class.java).sourceSets.getByName(SourceSet.MAIN_SOURCE_SET_NAME)

val task = tasks.create("sourcesJar", Jar::class.java, {
    it.dependsOn.add("classes")
    it.from(sourceSet.allSource)
    it.classifier = "sources"
})

artifacts.add("archives", task)
extensions.configure(PublishingExtension::class.java, {
    it.publications.create(CaseFormat.LOWER_HYPHEN.to(CaseFormat.LOWER_CAMEL, name), MavenPublication::class.java, {
        it.from(components.getByName("java"))
        it.artifact(task)
    })
})

I don’t know why that would make a difference, and I didn’t really want to look into it, since I already spent too long hitting my head against the wall, but I figured maybe this could help someone else later.