After declaring a custom `integrationTest` suite, how do you make it actually run as part of the build, and why isn't it included automatically?
answer
- only `test` auto-wired into check
- tasks.named("check") { dependsOn(...) }
- depend on the suite provider, not the name string
- shouldRunAfter(test) for ordering
- build → check → your suite
basics
~10 sCustom suites aren't wired into check by default. Add tasks.named("check") { dependsOn(testing.suites.named("integrationTest")) } so running check (and thus build) also runs integration tests.
solid answer
~40 sOnly the built-in `test` suite is wired into the `check` lifecycle task. A custom suite like `integrationTest` is registered and runnable (`gradle integrationTest`) but **will not run** during `check`/`build` until you explicitly make `check` depend on it. The idiomatic wiring is: ```kotlin tasks.named("check") { dependsOn(testing.suites.named("integrationTest")) } ``` This is deliberate: integration tests are often slow or require external resources, so Gradle leaves the decision to you. Once wired, `check` runs `test` then `integrationTest` (order isn't guaranteed unless you add `shouldRunAfter(test)`), and because `build` depends on `check`, CI that runs `build` will exercise the suite too. Prefer depending on the suite provider rather than hardcoding the task name so it stays lazy and rename-safe.
code
kotlin · 13 linestesting {
suites {
val integrationTest by registering(JvmTestSuite::class) {
targets {
all { testTask.configure { shouldRunAfter(test) } }
}
}
}
}
tasks.named("check") {
dependsOn(testing.suites.named("integrationTest"))
}go deeper
Know that check doesn't run custom suites until you add dependsOn.
Write the tasks.named("check") { dependsOn(...) } wiring and explain the build→check chain.
Distinguish dependsOn from shouldRunAfter, use lazy providers, and justify fail-fast ordering.
Define the org-wide convention (e.g. a convention plugin) so every module wires integration suites consistently into CI.
## The lifecycle gap Gradle's `check` task is the aggregate verification entry point; `build` depends on `check`. The `java` plugin wires the built-in **`test`** suite into `check` automatically. **Custom suites are not.** So after you declare an `integrationTest` suite you can run it directly (`gradle integrationTest`), but `gradle check` / `gradle build` will silently skip it. This is intentional — integration/functional suites are frequently slow, flaky, or need databases/containers, so Gradle refuses to assume they belong on the default verification path. ## Wiring it in The canonical fix is to add a dependency from `check` to the suite: ```kotlin tasks.named("check") { dependsOn(testing.suites.named("integrationTest")) } ``` Using `testing.suites.named("integrationTest")` returns a lazy provider; `dependsOn` accepts it and Gradle resolves it to the suite's run task. You could also write `dependsOn("integrationTest")`, but the provider form is lazier and survives refactors. ## Ordering vs. dependency `dependsOn` only guarantees the integration suite *runs*, not *when* relative to unit tests. To make integration tests run after unit tests (fail fast on the cheap ones first), add ordering inside the suite's target: ```kotlin testing { suites { val integrationTest by registering(JvmTestSuite::class) { targets { all { testTask.configure { shouldRunAfter(test) } } } } } } tasks.named("check") { dependsOn(integrationTest) } ``` `shouldRunAfter` is a *soft* ordering hint (not a hard dependency), so it won't force unit tests to run when you ask only for `integrationTest`, but it orders them when both are scheduled. ## Why not just call it from `test`? Making `test` depend on `integrationTest` would conflate scopes and force integration tests whenever anyone runs unit tests — the opposite of fail-fast. Wiring at the `check` aggregate keeps unit and integration runnable independently while still guaranteeing CI (`build` → `check`) covers both.
- Does wiring `check` to depend on the suite also affect `build`?Yes — `build` depends on `check`, so once `check` pulls in the suite, `gradle build` runs it too.
- What's the difference between `dependsOn(integrationTest)` and `shouldRunAfter(test)`?`dependsOn` guarantees execution; `shouldRunAfter` only orders the two when both are already scheduled, without forcing either.
- Why doesn't Gradle wire custom suites into `check` automatically?Integration suites are often slow or need external infra, so Gradle leaves the policy decision to the build author.
saying these in an interview costs you the question
- Assuming declaring the suite is enough to run it in CI.
- Making `test` depend on `integrationTest` (forces slow tests on every unit run).
- Using `mustRunAfter`/`shouldRunAfter` and expecting it to also force the dependency.