skip to content

Within `targets { }`, when would you use `all { }` versus configuring a specific named target, and what does iterating with `all` guarantee?

level: seniorimportance: should knowfreq 35%

answer

  1. all { } = every current + future target
  2. named("x") { } = one specific execution
  3. configureEach = strictly lazy variant
  4. shared config in all, overrides in named
  5. scopes config to the suite, not all Test tasks

basics

~20 s

all { } applies configuration to every target the suite has now or gains later. Use a named target when you need settings specific to one execution. all guarantees future targets get the config too.

solid answer

~40 s

`targets` is a container of targets. `targets { all { ... } }` registers a configuration action that runs for **every** target — including any added after the block executes — which is why it's the safe default for suite-wide settings on `testTask`. If a suite exposes multiple targets and you need to differentiate (say, different system properties per environment), you address one by name: `targets { named("integrationTestJdk21") { testTask.configure { ... } } }`. The `all` form is live and lazy, mirroring Gradle's `DomainObjectCollection.all` semantics, so it never misses a late-registered target. For the common single-target suite, `all { }` and naming the one target are equivalent, but `all` is more robust because it doesn't hardcode a target name that could change.

code

kotlin · 14 lines
kotlin
testing {
    suites {
        val integrationTest by registering(JvmTestSuite::class) {
            targets {
                all {
                    testTask.configure { useJUnitPlatform() }
                }
                named("integrationTest") {
                    testTask.configure { maxHeapSize = "2g" }
                }
            }
        }
    }
}

go deeper

for a junior

Recognize that all { } configures the suite's run; don't need the multi-target nuance.

for a middle

Use all { } for suite-wide settings and know named(...) exists for specifics.

for a senior

Explain live/future-inclusive semantics of all/configureEach and scope discipline vs. global withType<Test>.

for a principal

Design multi-target conventions (shared in all, overrides in named) and standardize them across modules.

## The targets container `targets` inside a suite is a Gradle domain object container of `JvmTestSuiteTarget`. Like other Gradle containers it supports `all { }`, `configureEach { }`, `named("x") { }`, and `withType`. ## `all { }` — live and inclusive ```kotlin targets { all { testTask.configure { useJUnitPlatform() systemProperty("spring.profiles.active", "test") } } } ``` `all` (and `configureEach`) attach an action that fires for **each current and future** target. This matters when a suite grows multiple targets later — your shared config still applies without edits. It follows the same eager-iteration-but-future-inclusive contract as `DomainObjectCollection.all`. (`configureEach` is the strictly-lazy variant and is generally preferred for pure configuration.) ## Named targets — per-execution differences When targets genuinely differ, reach a single one: ```kotlin targets { named("integrationTest") { testTask.configure { maxHeapSize = "2g" } } } ``` This is how you give one environment more memory, a different filter, or distinct JVM args while keeping common settings in `all { }`. ## Practical guidance - **Single-target suite (the usual case):** use `all { }` — it reads as "configure this suite's run" and won't break if the target name changes. - **Multi-target suite:** put shared config in `all { }`, then override specifics by `named(...)`. - Avoid hardcoding the target name unless you must address it specifically; the `all`/`configureEach` form is rename-safe and forward-compatible. ## Why not configure the Test task globally? Using `tasks.withType<Test>().configureEach { }` would touch *every* Test task in the build (unit + all suites). `targets { all { testTask.configure {} } }` scopes the change to one suite, which is what you almost always want.

  • How is `targets { all { } }` different from `tasks.withType<Test>().configureEach { }`?
    The former scopes to a single suite's target(s); the latter configures every `Test` task in the whole build, including unrelated suites.
  • Why might `all` be safer than `named("integrationTest")` for shared config?
    `all` doesn't hardcode a target name, so it survives renames and automatically covers any future targets added to the suite.

saying these in an interview costs you the question

  • Saying `all { }` only covers targets that exist at configuration time (it also covers future ones).
  • Using a global `withType<Test>` configuration when you only meant one suite.

context