skip to content

A JUnit 5 suite has many tests switched off by @Disabled and by custom conditional annotations. Once a quarter you want one run that executes all of them without touching the code. What does the junit.jupiter.conditions.deactivate configuration parameter do, how do you supply it, and what are the caveats?

level: seniorimportance: nice to knowfreq 22%

answer

  1. junit.jupiter.conditions.deactivate
  2. pattern matches condition CLASS names, not annotations
  3. `*` deactivates all — including DisabledCondition behind @Disabled
  4. -D system property | junit-platform.properties | launcher configurationParameter
  5. audit run, not a CI gate

basics

~20 s

junit.jupiter.conditions.deactivate takes a comma-separated pattern matched against the fully qualified class names of ExecutionCondition implementations; matching conditions are not evaluated, so their tests run. * deactivates all, including the one behind @Disabled. Supply it as a JVM system property, in junit-platform.properties, or via launcher config parameters.

solid answer

~50 s

`junit.jupiter.conditions.deactivate` is a Jupiter **configuration parameter**. Its value is a comma-separated list of patterns matched against the **fully qualified class name of each registered `ExecutionCondition`**. A matching condition is simply not evaluated, so whatever it would have disabled now runs. `*` matches everything; `*` also works inside a pattern (`org.junit.*`, `*.DatabaseCondition`, `*System*`). Because `@Disabled` is implemented by `org.junit.jupiter.engine.extension.DisabledCondition`, deactivating all conditions runs the `@Disabled` tests too — that is the classic "quarterly audit of everything we switched off" run. Three ways to supply it: a JVM system property on the test JVM (`-Djunit.jupiter.conditions.deactivate=*`), a `junit-platform.properties` file at the classpath root, or `configurationParameter(...)` on a `LauncherDiscoveryRequest`. Caveats: it is all-or-nothing per matching condition and global for the run, so genuinely inapplicable tests (wrong OS, missing service) will run and fail; and it does not affect aborts raised at runtime from inside a test body, which are not conditions.

code

java · 9 lines
java
LauncherDiscoveryRequest request = LauncherDiscoveryRequestBuilder.request()
        .selectors(selectPackage("com.example"))
        .configurationParameter("junit.jupiter.conditions.deactivate", "*DisabledCondition")
        .build();

Launcher launcher = LauncherFactory.create();
SummaryGeneratingListener listener = new SummaryGeneratingListener();
launcher.execute(request, listener);
listener.getSummary().printTo(new PrintWriter(System.out));

go deeper

for a junior

Knowing the parameter exists and that * runs everything including @Disabled tests is enough at this level.

for a middle

Be precise that patterns match condition class names, and name the three ways to supply a Jupiter configuration parameter.

for a senior

Discuss narrowing the pattern, running it on a schedule rather than in the PR gate, and triaging the three classes of outcome (passes again, fails for the old reason, fails for a new reason).

for a principal

Treat it as part of suite-debt policy: how disabled tests are inventoried and reviewed, who owns triage of the audit run, and what expiry rules apply to a test that has been off for a quarter.

## What the parameter is JUnit Jupiter reads *configuration parameters* — plain string key/value pairs — to tune engine behaviour. `junit.jupiter.conditions.deactivate` is one of them, and it exists for exactly one purpose: to switch off `ExecutionCondition` extensions for a run, so that tests those conditions would have skipped are executed instead. Its value is a **comma-separated list of patterns**, and each pattern is matched against the **fully qualified class name of the condition implementation** — not against the annotation name, not against the test name. Wildcards use `*`: - `*` — deactivate every condition; - `org.junit.*` — every condition in `org.junit` and its subpackages (all the built-ins); - `*.DatabaseCondition` — one class regardless of package; - `*System*` — any condition class whose name contains `System`; - `com.example.FlagCondition, com.example.LicenceCondition` — an explicit list. A condition whose class name matches is **not evaluated at all**. It does not "return enabled"; the engine skips the evaluation, so the node proceeds as if that condition were never registered. ## Why the built-ins are included The conditional annotations are conditions: `@Disabled` is backed by `DisabledCondition`, `@EnabledOnOs` by `EnabledOnOsCondition`, `@EnabledIfEnvironmentVariable` by its own condition class, and so on. There is nothing privileged about them, so `junit.jupiter.conditions.deactivate=*` also runs everything annotated `@Disabled`. That is the headline use case: an occasional run that answers "of the tests we turned off, which ones actually still pass?" — cheap rot detection for a suite that has accumulated disabled tests over a year. ## How to supply it Configuration parameters reach the engine through three channels, all equivalent from Jupiter's point of view: 1. **JVM system property on the test JVM** — `-Djunit.jupiter.conditions.deactivate=*`. This is the natural choice for an ad-hoc or scheduled run because nothing in the repository changes. 2. **`junit-platform.properties`** — a properties file at the root of the classpath containing `junit.jupiter.conditions.deactivate=org.junit.*`. Good for a permanent, checked-in default; bad for an occasional audit, because it applies to every run. 3. **Programmatically via the `Launcher` API** — `LauncherDiscoveryRequestBuilder.request().configurationParameter("junit.jupiter.conditions.deactivate", "*")`, used when you drive JUnit yourself or from a custom runner. Inside an extension you can read the effective value with `ExtensionContext.getConfigurationParameter(String)`, which resolves through the same precedence. ## Caveats worth naming **It is a blunt instrument.** Deactivation is per condition class and global for the whole run. Deactivating everything means an OS-gated test runs on the wrong OS and a service-gated test runs without the service — those failures are expected noise, and someone must triage them. Prefer the narrowest pattern that answers your question: `*.DisabledCondition` to unmask only `@Disabled` tests, leaving genuine platform gates intact. **It does not touch runtime aborts.** A test that bails out mid-body via an assumption is not using a condition; it aborts during execution and no configuration parameter changes that. Only pre-execution `ExecutionCondition` evaluation is affected. **It changes only whether the condition is consulted.** It cannot flip a condition's answer — there is no "force disabled" mode — and it cannot deactivate conditions selectively per test class; the pattern is matched against condition classes for the entire run. **Failures are the point, not a defect.** A run with conditions deactivated is an audit, not a gate. Do not wire it into the pull-request pipeline where its noise trains people to ignore red; run it on a schedule and treat the output as a work list. ## Where it fits in a suite strategy Disabled tests are silent debt: they still compile, so they look maintained, but they verify nothing. Two mechanisms keep that debt visible — always requiring a reason on `@Disabled` (the reason appears in the skip output), and a periodic deactivated run that tells you which of those tests now pass, which fail for the original reason, and which fail for a brand-new reason because the production code moved on. The third failure class is the valuable one: it is a bug the suite would have caught if the test had been running. If you write your own conditions, keep the class names meaningful (`DockerAvailableCondition`, not `Cond1`), because those names are the handle by which anyone can later switch them off.

  • You want to unmask only the `@Disabled` tests and leave the OS and JRE gates working. What pattern do you use?
    Target just the class behind `@Disabled`: `junit.jupiter.conditions.deactivate=*DisabledCondition` (or the fully qualified `org.junit.jupiter.engine.extension.DisabledCondition`). Patterns match condition class names, so the operating-system and JRE conditions keep evaluating and their tests stay correctly skipped.
  • Does this parameter also cause a test that aborts partway through its body to run to completion?
    No. The parameter only controls whether registered `ExecutionCondition` extensions are evaluated before execution. A test that aborts during execution — for example when a runtime precondition inside the body is not met — is reported as aborted regardless of this setting; there is no configuration parameter that disables that path.

saying these in an interview costs you the question

  • Thinking the pattern matches annotation names such as `@Disabled` rather than condition class names
  • Believing it can force tests to be disabled as well as enabled
  • Wiring the deactivated run into the normal CI gate and then ignoring the resulting red
  • Assuming it also overrides runtime aborts raised from inside a test body
  • Claiming built-in conditions are exempt from deactivation

context