Combining two configurations' classpaths

I’d like to create a project containing (architecture) tests so that I only have to define these tests once. The idea is that the tests run in the context of each (other) project, so that I can enforce certain architecture decisions using the automated test suite.

I got this to work by defining new configurations, so that I can create a combined context containing both the (global) tests and the individual project’s code.

My question is about adding files to the source set of my new configuration. In Groovy I got this to work using the following snippet. For Kotlin, I have to loop over all files and add them individually. Is there a better way (for this specific issue, of for the broader idea in general)?

Groovy:

exposedTestRuntimeClasspath sourceSets.test.runtimeClasspath.files

Kotlin:

sourceSets.getByName("test").runtimeClasspath.files.forEach {
    add("exposedTestRuntimeClasspath", it) {}
}

Wouldn’t it work to just make the exposedTestRuntimeClasspath extend the testRuntimeClasspath?

Btw. why do you do project.dependencies.platform instead of simply platform?
Like you have it you only need if you do it in the new JVM Test Suites block.

Oh, that was a copy-paste mistake. Thanks!

I wasn’t able to make it work. In order for the actual instance of the sharedTest task (for example :application:sharedTest) to include the test classes from the test sourceset of my architecture-tests project, I need to define the following in my architecture-tests project:

artifacts {
  sourceSets.named("test") {
          output.classesDirs.files.forEach {
              add("exposedTestClasses", it) {
                  builtBy(tasks.named("compileTestJava"))
              }
          }
  }
}

Without this, with or without extendsFrom(configurations.testImplementation.get()) for my exposedTestClasses configuration, the task created based on exposedTestClasses does not see the exposed test classes (it does not have any inputs).

I just refered to the exposedTestRuntimeClasspath configuration, not the exposedTestClasses one.

Sadly, no. If I remove the artifact block for exposedTestRuntimeClasspath and add exposedTestRuntimeClasspath.extendsFrom(configurations.testRuntimeClasspath.get()) I get a ClassNotFoundException in each instance of the sharedTest task execution:

java.lang.ClassNotFoundException: de.cotto.playground.architecture.ArchUnitTest

(ArchUnitTest is defined in :architecture-tests, it is the test code I’d like to share with other projects)

Hm, sad. :frowning:
Then you maybe do not get around iterating over the files.
At least not without an accepted feature request on Gradle side.
Because that you can supply a list there is part of the dark Groovy magic Gradle put in place.
And the Kotlin DSL can not leverage that of course.
You could at most write some own extension function that does the iteration for you .

1 Like