When wiring an integrationTest suite's dependencies, when would you depend on testFixtures(project()) instead of just project()?
answer
- java-test-fixtures plugin
- testFixtures(project()) = shared test helpers
- project() = production code only
- fixtures stay out of prod jar
- testFixturesApiElements variant
basics
~10 sproject() 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 sA 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 linesplugins {
`java-library`
`java-test-fixtures`
}
testing {
suites {
val integrationTest by registering(JvmTestSuite::class) {
dependencies {
implementation(project())
implementation(testFixtures(project()))
}
}
}
}go deeper
Know that production code comes from project(); awareness that a separate mechanism exists for shared test helpers is enough.
Explain the java-test-fixtures plugin, the testFixtures(project()) helper, and why fixtures stay out of the production artifact.
Discuss the underlying variant selection (testFixturesApiElements) and cross-module fixture reuse via testFixtures(project(":x")).
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.