skip to content

When wiring an integrationTest suite's dependencies, when would you depend on testFixtures(project()) instead of just project()?

level: middleimportance: should knowfreq 35%

answer

  1. java-test-fixtures plugin
  2. testFixtures(project()) = shared test helpers
  3. project() = production code only
  4. fixtures stay out of prod jar
  5. testFixturesApiElements variant

basics

~10 s

project() gives the suite your production classes. testFixtures(project()) additionally exposes shared test-only helpers (builders, fakes, fixtures) published by the java-test-fixtures plugin, so multiple suites reuse them.

solid answer

~30 s

A suite's `dependencies { implementation(project()) }` pulls in production code only. Reusable **test** helpers — object mothers, fake clients, base test classes — should live in a `testFixtures` source set provided by the `java-test-fixtures` plugin, then be consumed via `implementation(testFixtures(project()))`. This keeps fixtures out of your published production artifact while letting the `test` suite and the `integrationTest` suite both share them. Internally `testFixtures(project())` selects the project's `testFixturesApiElements`/`testFixturesRuntimeElements` outgoing variants rather than the main API/runtime variants. So the rule of thumb: `project()` for production code under test, `testFixtures(project())` to reuse shared test scaffolding across suites without duplication.

code

kotlin · 15 lines
kotlin
plugins {
  `java-library`
  `java-test-fixtures`
}

testing {
  suites {
    val integrationTest by registering(JvmTestSuite::class) {
      dependencies {
        implementation(project())
        implementation(testFixtures(project()))
      }
    }
  }
}

go deeper

for a junior

Know that production code comes from project(); awareness that a separate mechanism exists for shared test helpers is enough.

for a middle

Explain the java-test-fixtures plugin, the testFixtures(project()) helper, and why fixtures stay out of the production artifact.

for a senior

Discuss the underlying variant selection (testFixturesApiElements) and cross-module fixture reuse via testFixtures(project(":x")).

for a principal

Establish a convention for where shared test scaffolding lives across modules, balancing reuse against build-graph coupling and variant publishing.

## The two things a suite might need 1. **Production code under test** — your `main` classes. Wired with `implementation(project())`. 2. **Shared test scaffolding** — helpers that only make sense in tests (test data builders, in-memory fakes, base classes, custom assertions). These should NOT ship in your production jar. ## The `java-test-fixtures` plugin Applying `java-test-fixtures` creates a `testFixtures` source set (`src/testFixtures/java` / `kotlin`) and a set of variants: - `testFixturesApiElements` / `testFixturesRuntimeElements` — outgoing, what consumers see. - A `testFixtures(project())` helper that resolves those variants. Fixtures can themselves depend on `main` (via `testFixturesImplementation(project())` implicitly) so they can build helpers around production types. ## Wiring it in a suite ```kotlin plugins { `java-library` `java-test-fixtures` } testing { suites { val integrationTest by registering(JvmTestSuite::class) { dependencies { implementation(project()) // production code implementation(testFixtures(project())) // shared test helpers } } } } ``` Both the built-in `test` suite and `integrationTest` can consume the same fixtures, eliminating copy-paste of test utilities. ## Why not just put helpers in main? Because they'd leak into the published artifact and onto every downstream consumer's classpath. Test fixtures are a separate, optional variant — consumers only pull them when they explicitly ask via `testFixtures(...)`. ## Cross-project reuse `testFixtures(project(":domain"))` lets one module reuse another module's published fixtures — handy for shared test base classes across a multi-module build. ## Takeaway Use `project()` for the code being tested; reach for `testFixtures(project())` whenever a helper is needed by more than one suite or more than one module, so you share it through a proper variant instead of duplicating or polluting production.

  • What plugin must be applied for `testFixtures(project())` to resolve?
    `java-test-fixtures`, which creates the `testFixtures` source set and the `testFixturesApiElements`/`testFixturesRuntimeElements` outgoing variants that the helper selects.
  • Why is putting shared test helpers in `main` a bad idea?
    They would leak into the published production artifact and onto every downstream consumer's classpath; test fixtures are an optional, separately-resolved variant instead.

saying these in an interview costs you the question

  • Saying `testFixtures(project())` works without applying the `java-test-fixtures` plugin.
  • Putting reusable test helpers in the main source set, polluting the production jar.

context