skip to content

When configuring suites, when do you use `getting` versus `registering` (or `getByName` vs `register`), and why does it matter for the default `test` suite?

level: middleimportance: should knowfreq 35%

answer

  1. NamedDomainObjectContainer semantics
  2. getting/getByName = configure existing
  3. registering/register = create new
  4. test already registered by java plugin
  5. lazy accessors help config cache

basics

~10 s

Use getting/getByName to configure an existing suite like the default test suite. Use registering/register to create a brand-new suite. Calling register("test") fails because test already exists.

solid answer

~40 s

The `suites` container is a `NamedDomainObjectContainer<TestSuite>`, so the same get-vs-register semantics as tasks apply. The default `test` suite is **already registered** by the java plugin, so you *configure* it with `val test by getting(JvmTestSuite::class) { … }` (Kotlin delegate) or `getByName("test")`. Trying to `register("test")` or `registering` it throws because the name is taken. New suites — which belong to sibling topics — use `register`/`registering`, which is lazy: the suite (and its source set, configurations, and tasks) is only realized when something needs it. Within the basics, the practical rule is: the default suite uses `getting`; you only `register` when introducing additional suites. Using lazy accessors (`getting`/`registering`) over eager `getByName`/`create` keeps configuration deferred, which matters for configuration-time performance and configuration cache compatibility.

code

kotlin · 9 lines
kotlin
testing {
    suites {
        // existing default suite -> getting
        val test by getting(JvmTestSuite::class) {
            useJUnitJupiter()
        }
        // register("test") here would FAIL: name already taken
    }
}

go deeper

for a junior

Recall that test already exists so you configure it (get), you don't create it.

for a middle

Distinguish get vs register, explain why register("test") fails, and that the java plugin pre-registers test.

for a senior

Discuss laziness, NamedDomainObjectContainer semantics, and configuration-cache implications of eager vs lazy accessors.

for a principal

Tie lazy registration discipline to scalable build configuration across large multi-module repos.

## The container model `testing.suites` is a `NamedDomainObjectContainer<TestSuite>`. Named domain object containers in Gradle distinguish two operations: - **register / registering** — declare a *new* element lazily. The object is created only when realized (referenced/needed). Throws if the name already exists. - **getting / getByName** — obtain an *existing* element to configure it. Throws if the name does not exist. ## Why it matters for `test` The java plugin registers the `test` suite for you. So the suite already exists by the time your `build.gradle.kts` runs. Therefore: ```kotlin testing { suites { // CORRECT: configure the pre-existing default suite val test by getting(JvmTestSuite::class) { useJUnitJupiter() } } } ``` If you instead wrote `val test by registering(JvmTestSuite::class) { … }`, Gradle would fail with a *cannot add … already exists* error, because you're trying to create something that's already there. ## Lazy vs eager Kotlin DSL delegates: - `by getting(...)` → lazy `named(...)`-style access. - `by registering(...)` → lazy registration. Groovy equivalents `getByName(...)`/`create(...)` are eager. Prefer the lazy forms: deferring configuration avoids realizing objects you might not need and is friendlier to the **configuration cache**. ## Quick decision rule ``` Does the suite already exist (e.g. `test`)? -> getting / getByName Am I introducing a new suite? -> registering / register ``` For the *basics* of the DSL, you almost always use `getting` for `test`; `register` shows up once you add custom suites.

  • Why does `register("test")` fail?
    Because the java plugin already registered a suite named `test`; named containers reject creating a duplicate name. Use `getting`/`getByName` to configure it instead.
  • Why prefer `getting`/`registering` over `getByName`/`create`?
    They are lazy: configuration is deferred until the object is realized, avoiding unnecessary work and improving configuration-cache compatibility.

saying these in an interview costs you the question

  • Using `register("test")` to configure the default suite.
  • Claiming `getting` creates a suite — it only retrieves an existing one.
  • Saying eager `create`/`getByName` is preferred for performance.

context