skip to content

When you register a suite named integrationTest, what exact names do the derived source set, task, and configurations get, and why does the suite name matter?

level: middleimportance: must knowfreq 50%

answer

  1. suite name = convention key
  2. source set src/<name>
  3. task = <name>
  4. <name>Implementation / RuntimeOnly configs
  5. rename = renames everything

basics

~10 s

Everything is named after the suite. Source set: integrationTest (src/integrationTest/...). Task: integrationTest. Configurations: integrationTestImplementation, integrationTestRuntimeOnly, integrationTestCompileOnly, etc. So the suite name is the single key that derives all related artifacts.

solid answer

~30 s

The suite name is the convention key. Registering `integrationTest` gives you: a **source set** `integrationTest` mapped to `src/integrationTest/{java,kotlin,resources}`; a **Test task** `integrationTest`; and the dependency **configurations** `integrationTestImplementation`, `integrationTestCompileOnly`, `integrationTestRuntimeOnly`, `integrationTestAnnotationProcessor`, plus the resolvable/consumable classpath configurations Gradle keeps internally. Because all of these derive from the name, you reference them consistently elsewhere — e.g. `dependencies { integrationTestImplementation(project()) }` or `tasks.named("integrationTest")`. Choosing a clear, conventional name (`integrationTest`, `functionalTest`) keeps the directory layout and task names discoverable and matches what shared convention plugins expect. Renaming the suite renames every derived artifact, so the name is effectively the suite's public contract.

code

kotlin · 11 lines
kotlin
testing {
    suites {
        val integrationTest by registering(JvmTestSuite::class)
    }
}

// derived names referenced elsewhere:
dependencies {
    "integrationTestImplementation"(project())
}
tasks.named<Test>("integrationTest") { /* ... */ }

go deeper

for a junior

Recall that the source set, task, and configs are all named after the suite.

for a middle

Enumerate the derived names precisely and reference them correctly in dependencies/tasks blocks.

for a senior

Explain the name-as-contract idea and the Kotlin DSL accessor caveat for dynamically created configurations.

for a principal

Mandate naming conventions across modules so shared convention plugins can rely on stable suite/task names.

## The name is the key A `JvmTestSuite` has exactly one identifier — its registration name — and the JVM Test Suite plugin uses it to derive every related build artifact by convention. Pick `integrationTest` and you get a deterministic, predictable set of names. ## Derived artifacts for a suite named `integrationTest` | Artifact | Name / path | |---|---| | Source set | `integrationTest` → `src/integrationTest/java`, `.../kotlin`, `.../resources` | | Test task | `integrationTest` (type `Test`) | | Implementation config | `integrationTestImplementation` | | Compile-only config | `integrationTestCompileOnly` | | Runtime-only config | `integrationTestRuntimeOnly` | | Annotation processor config | `integrationTestAnnotationProcessor` | | Resolvable classpaths | `integrationTestCompileClasspath`, `integrationTestRuntimeClasspath` | The built-in suite is simply named `test`, which is why its directory is `src/test` and its task is `test` — same convention, special-cased name. ## Referencing them Because names are derived, you address artifacts by their conventional name: ```kotlin dependencies { "integrationTestImplementation"(project()) } tasks.named<Test>("integrationTest") { maxParallelForks = 1 } ``` In the Kotlin DSL, configurations created after the build script's accessors are generated may need the string form (`"integrationTestImplementation"(...)`) inside `dependencies { }` unless you reference the suite's own `dependencies` block. ## Why a good name matters - **Discoverability** — `./gradlew tasks` shows `integrationTest`; the layout under `src/integrationTest` is obvious. - **Convention plugins** — shared build logic often does `tasks.named("integrationTest")`; a non-standard name breaks it. - **Stable contract** — rename the suite and every derived name changes, breaking any code that referenced the old names. Treat the name as public API. ## Practical guidance Use intent-revealing, camelCase names: `integrationTest`, `functionalTest`, `endToEndTest`. Avoid spaces, hyphens, or names that collide with existing tasks/source sets.

  • What is the source directory for a suite named functionalTest?
    `src/functionalTest/java` (and `kotlin`/`resources`) — the source set path always matches the suite name.
  • Why might `integrationTestImplementation(...)` not resolve as a typed accessor in the Kotlin DSL?
    Typed configuration accessors are generated from the build script's static view; configurations created dynamically by a registered suite may require the string-quoted form inside `dependencies { }`, or you declare deps inside the suite's own `dependencies` block.

saying these in an interview costs you the question

  • Saying the source directory is fixed (e.g. always `src/integrationTest`) regardless of suite name — it tracks the name.
  • Treating the suite name as cosmetic — it is the contract that derives every artifact.

context