How do you consume test fixtures from another project in the same build, and how does it differ from consuming published external fixtures?
answer
- testFixtures(project(':lib'))
- testFixtures('g:a:v') external
- capability group:name-test-fixtures
- external needs Gradle Module Metadata
- POM can't express variants
basics
~10 sUse the testFixtures() helper inside a dependency declaration: testImplementation(testFixtures(project(":lib"))) for a local project, or testImplementation(testFixtures("g:a:v")) for an external module. External requires the producer to publish Gradle Module Metadata.
solid answer
~40 sYou wrap the dependency in the `testFixtures(...)` notation so Gradle's variant-aware resolution picks the fixtures variant rather than the main artifact. For a sibling module in the same build: ```kotlin testImplementation(testFixtures(project(":lib"))) ``` For an externally published library: ```kotlin testImplementation(testFixtures("com.example:lib:1.0")) ``` The key difference: the **local case just works**, because Gradle knows the producer's variants directly from the build model. The **external case requires Gradle Module Metadata** (`module.json`) to be published alongside the POM — that metadata is what declares the test-fixtures variant and its capability. A plain Maven POM has no way to express it, so without module metadata Gradle can't resolve `testFixtures("...")` and you get a 'no matching variant' error. `gradle publish` with `maven-publish` emits this metadata by default.
code
kotlin · 8 linesdependencies {
// same build — resolves directly from the producer's model
testImplementation(testFixtures(project(":domain")))
// published library — requires the producer to have published
// Gradle Module Metadata (*.module), not just a POM
testImplementation(testFixtures("com.example:payments:2.1.0"))
}go deeper
Recall the two syntaxes: testFixtures(project(':lib')) and testFixtures('g:a:v').
Explain the capability/variant selection and that external consumption requires Gradle Module Metadata, not just a POM.
Diagnose 'no matching variant providing capability' errors and tie them back to publishing configuration.
Set publishing conventions so internal libraries reliably emit module metadata, enabling fixtures reuse across the org.
## The `testFixtures(...)` selector Test fixtures are exposed as a distinct **variant** carrying a **capability** named `group:module-test-fixtures`. By default a dependency declaration selects the main runtime/api variant. Wrapping the dependency in `testFixtures(...)` adds a *capability requirement* that tells variant-aware resolution: "give me the test-fixtures variant of this module, not its main jar." ```kotlin dependencies { testImplementation(testFixtures(project(":lib"))) // local project testImplementation(testFixtures("com.example:lib:1.0")) // external module } ``` ## Local (project) consumption Within one multi-project build, Gradle has the full producer build model, including the `testFixturesApiElements`/`testFixturesRuntimeElements` outgoing configurations the `java-test-fixtures` plugin created. Resolution is immediate — no publishing, no metadata file. This is the common case for sharing object mothers and fakes across modules. ## External consumption needs Gradle Module Metadata For a library pulled from a repository, Gradle has only what was published. A traditional **Maven POM cannot describe multiple variants or capabilities**. Gradle's solution is **Gradle Module Metadata** — a `*.module` JSON file published next to the POM by `maven-publish`. It enumerates variants (including test-fixtures) and their capabilities and attributes. If the producer published only a POM (no module metadata), the consumer's `testFixtures("...")` resolves to *nothing* and the build fails with a 'Unable to find a variant ... providing capability ...-test-fixtures' error. So external fixture consumption is a two-sided contract: producer must publish module metadata, consumer must request the variant. ## Practical gotchas - The producing module must apply `java-test-fixtures` for the variant to exist at all. - Use the configuration appropriate to where you need them: `testImplementation` for normal tests, or `integrationTestImplementation` for a custom suite. - Transitively, `testFixturesApi` dependencies of the producer arrive on your compile classpath; `testFixturesImplementation` ones only at runtime.
- A teammate published a library with `java-test-fixtures` applied but `testFixtures("...")` fails to resolve in your build. What's the likely cause?Gradle Module Metadata wasn't published (e.g. metadata publication was disabled, or an old publishing setup emitted only a POM). The plain POM can't describe the fixtures variant, so the capability can't be found.
- Can you depend on the fixtures of a project without depending on its main jar?Yes — `testFixtures(project(":lib"))` requests only the fixtures variant. However, the fixtures' own `testFixturesApi` dependencies (which may include the main module if declared) still come along transitively.
saying these in an interview costs you the question
- Thinking a normal `project(":lib")` dependency gives you the fixtures — it gives the main variant only.
- Assuming external fixtures resolve from a Maven POM alone without Gradle Module Metadata.