A teammate sets `ignoreFailures`, `failFast`, and `testLogging` thinking they all relate to handling failures. Explain how these three differ and how they compose.
answer
- three orthogonal axes
- failFast = when execution stops
- ignoreFailures = build outcome
- testLogging = console output only
- can be freely combined
basics
~20 sThey answer different questions: failFast = when execution stops (first failure vs. run all); ignoreFailures = whether the build fails on test failures; testLogging = what prints to the console. They are orthogonal and can be combined.
solid answer
~40 sThese three Test-task settings are independent axes. `failFast` (default false) controls **execution termination** — stop after the first failure or run the whole suite. `ignoreFailures` (default false) controls the **build outcome** — whether failing tests make the build exit non-zero. `testLogging` controls **console observability** — which events and how much of a stack trace appear, with zero effect on outcome or scheduling. Because they're orthogonal you can mix them: e.g. local dev might use `failFast = true` + verbose `testLogging` for quick, readable feedback; a report-always module might use `ignoreFailures = true` + a downstream gate; release runs leave failFast/ignoreFailures false and crank logging to FULL. The classic mistake is expecting `testLogging` or `ignoreFailures` to change *which* tests run, or expecting `failFast` to alter the build's pass/fail decision.
code
kotlin · 7 linestasks.named<Test>("test") {
failFast = true // when to stop
ignoreFailures = false // build outcome
testLogging { // what prints
exceptionFormat = org.gradle.api.tasks.testing.logging.TestExceptionFormat.FULL
}
}go deeper
Just recognize the three are different and name one effect of each.
Cleanly separate the three axes (when-stop / build-outcome / console) and give a default for each.
Reason about composition, edge combinations, and the right home (CLI vs. script vs. convention plugin) for each setting.
Define org policy: convention-plugin testLogging defaults, gated ignoreFailures, failFast off shared scripts; tie to CI cost, readability, and not hiding regressions.
## Three orthogonal axes All three live on the `Test` task but answer distinct questions: | Property | Axis | Default | Effect | |---|---|---|---| | `failFast` | When does execution stop? | false | true → abort the run on the first failure | | `ignoreFailures` | Does the build fail? | false | true → build exits 0 even with failing tests | | `testLogging` | What is printed? | FAILED + SHORT | selects events + stack-trace verbosity | ## Why they're independent - `failFast` schedules/cancels test execution. It changes the *set of tests that actually ran*, but not the verdict on those that did. - `ignoreFailures` is evaluated **after** the run completes; it only decides whether to throw. It never changes scheduling or logging. - `testLogging` is a pure side-channel: it formats events as they occur. Removing all logging wouldn't change results or exit codes. ## Composition examples ```kotlin import org.gradle.api.tasks.testing.logging.TestExceptionFormat import org.gradle.api.tasks.testing.logging.TestLogEvent // Local inner loop: stop early, show everything, still fail the build tasks.named<Test>("test") { failFast = true ignoreFailures = false testLogging { events(TestLogEvent.PASSED, TestLogEvent.FAILED, TestLogEvent.SKIPPED) exceptionFormat = TestExceptionFormat.FULL } } ``` ```kotlin // Report-always aggregation module: never fail here, gate downstream tasks.named<Test>("integrationTest") { ignoreFailures = true finalizedBy("verifyAggregatedResults") } ``` ## Edge combinations - `failFast = true` + `ignoreFailures = true`: stop at the first failure **and** keep the build green. Rare, but valid — proves the axes are separate. - Verbose `testLogging` with `ignoreFailures = true`: you'll see the failures clearly in the console even though the build passes — which is exactly why you need an external gate, since humans/CI may glance at exit code only. ## Decision guidance - Make `failFast` a per-developer CLI choice (`--fail-fast`), not a shared script default. - Treat `ignoreFailures` as a deliberate, gated exception — never a blanket setting. - Standardize `testLogging` in a convention plugin for consistent, readable CI output.
- Which of these three would change the actual set of tests that executed in a run?Only `failFast`, because it aborts scheduling after the first failure so later tests never run. `ignoreFailures` and `testLogging` don't affect which tests execute.
- If a build has verbose testLogging showing failures but exits 0, what's wrong and how do you fix it?`ignoreFailures` is likely true, so the build passes despite failures. Either set it back to false, or keep it and add a downstream verification task/CI step that inspects the JUnit XML and fails on errors.
- Where should each setting ideally live?failFast on the CLI per developer; ignoreFailures only behind an explicit gate in specific modules; testLogging centralized in a convention plugin for consistent output.
saying these in an interview costs you the question
- Lumping all three as 'failure handling' and assuming they overlap.
- Believing testLogging or ignoreFailures changes which tests run.
- Believing failFast changes the build's pass/fail verdict.