javagradledependency-managementgradle-kotlin-dsljava-test-fixtures

Gradle test fixtures plugin and core module dependencies


I have a project built with Gradle version 6.4 and JDK 8. I'm trying to use the Gradle plugin for Test Fixtures (java-test-fixtures) but I have some issues with the dependencies.

According to the Gradle page linked above, the project should be structured like this:

core-module
-- src
   -- main
      -- java
   -- test
      -- java
   -- testFixtures
      -- java

While the build.gradle.kts file has the following dependencies section:

dependencies {
    api("com.my.external.project:1.0")
    // ... more API dependencies

    testFixturesCompileOnly(project(":core-module"))
    testFixturesApi("junit:junit:4.12")
    // ... more test dependencies
}

Now, in IntelliJ (the IDE I'm using) classes in the testFixtures/java source folder see the classes in the main/java source folder. So I can add new Java classes under testFixtures/java that have dependencies on those under main. However, I won't be able to import the dependencies from the external library com.my.external.project:1.0. The problem is confirmed when I try to run the Gradle task compileTestFixturesJava.

I can duplicate the entry in the dependencies section; e.g. I can add:

testFixturesImplementationOnly("com.my.external.project:1.0")

But that is not really what I expect to do; especially when I have dozens of dependencies.

I could also define the dependencies in an array and run a for-each over them. Still, this is not the cleanest solution.

Is there a clean solution that will allow the testFixtures module to use the dependencies declared in the main module?


Solution

  • Most important concept in the Gradle java-test-fixtures plugin is stated in their documentation:

    [this plugin] will automatically create a testFixtures source set, in which you can write your test fixtures. Test fixtures are configured so that:

    • they can see the main source set classes
    • test sources can see the test fixtures classes

    This plugin will indeed create the following dependencies: main <-- testFixtures , and testFixtures <-- test

    In your case, testFixtures module should automatically depend on main sources, and also on main dependencies declared in api scope ( com.my.extenal.project:1.0)

    See a similar example in a valid sample project here https://github.com/mricciuti/so-64133013 :

    Note that testFixtures will not inherit dependencies from the test module: if you need to use such libraries in this module (eg. JUnit, Mockito, ...) you will need to declare explicit dependency , using testFixturesImplementation or testFixturesApi configuration.

    See example in core-module

    plugins {
        id ("java-library")
        id ("java-test-fixtures")
    }
    dependencies {
        // Main dependencies
        //   will be available in "testFixture" as well thanks to "api" configuration
        api("org.apache.commons:commons-lang3:3.9")
        api(project(":utils-module"))
    
        // Testfixture dependencies
            // ==> mockito lib will be available in testFixture module and also in consumer modules (e.g test)
        testFixturesApi("org.mockito:mockito-core:3.5.13")
    
        // Test dependencies
           // dependencies specific to the "test" module; not visible from "testFixtures"
        testImplementation("org.junit.jupiter:junit-jupiter-api:5.3.1")
        testRuntimeOnly ("org.junit.jupiter:junit-jupiter-engine:5.3.1")
    }