skip to content

@Disabled

@Disabled skips a test or class (the JUnit 5 successor to @Ignore), while the @EnabledOnOs and @EnabledIf family skip conditionally. Interviewers may ask why an unconditionally disabled test with no reason is a smell.

part ofJavaoverview, primer and where to startread it →
on this pageshow

questions

5

What does the @Disabled annotation do in JUnit 5, and what is the recommended way to use it?

level: juniorimportance: must knowfreq 70%

answer

  1. Unconditional skip - method or whole class
  2. Optional reason String, always supply it
  3. Replaces JUnit 4 @Ignore
  4. org.junit.jupiter.api.Disabled
  5. Reported as 'skipped', not pass/fail

basics

~20 s

@Disabled tells JUnit to skip a test method or whole test class instead of running it. You should always pass a reason string, like @Disabled("flaky on CI - see TICKET-123"), so it is clear why it is off.

solid answer

~40 s

@Disabled is JUnit 5's annotation for unconditionally skipping a test. Put it on a single @Test method to skip that one test, or on the test class to skip every test in it. The optional String argument documents why the test is disabled (e.g. @Disabled("broken pending fix #42")) and JUnit reports it in the test output, so reviewers and future readers know the reason. A skipped test is not a passing or failing test: it shows up as 'skipped' in reports. Always provide a reason - a disabled test with no explanation is hard to clean up later. @Disabled is the JUnit 5 replacement for JUnit 4's @Ignore; the import is org.junit.jupiter.api.Disabled.

code

java · 16 lines
java
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;

class PaymentTest {

    @Test
    void chargesValidCard() {
        // runs normally
    }

    @Test
    @Disabled("gateway sandbox down - re-enable after PAY-204")
    void refundsFailedCharge() {
        // skipped, with a documented reason
    }
}

go deeper

for a junior

Knows @Disabled skips a test and that you can put it on a method or a class, and that you should add a reason string.

for a middle

Distinguishes skipped from passed/failed in reports, knows it replaces @Ignore and the correct import, and treats a disabled test as a temporary, tracked decision.

for a senior

Argues against long-lived disabled tests (false coverage), prefers conditional annotations over blanket @Disabled where a real condition exists, and enforces reason/ticket conventions in review.

for a principal

Sets team policy on disabled tests (e.g. fail the build on un-ticketed @Disabled, periodic audits), and weighs disabling vs quarantining vs deleting flaky tests at scale.

## What is a test, and what does 'disabled' mean? A **test** is a small method that checks your code behaves correctly. In **JUnit 5** (the standard Java testing framework; its API package is `org.junit.jupiter.api`), you mark such a method with `@Test`. When you run the test suite, JUnit executes every `@Test` method and reports each as **passed**, **failed**, or **skipped**. A **disabled** (skipped) test is one JUnit deliberately does *not* run. It counts as neither pass nor fail - it is simply reported as skipped. ## The @Disabled annotation `@Disabled` is the annotation that marks a test method, or an entire test class, to be **unconditionally skipped**. 'Unconditionally' means it is *always* skipped - no logic decides; it is just off. ```java import org.junit.jupiter.api.Disabled; import org.junit.jupiter.api.Test; class OrderTest { @Test @Disabled("flaky timing assertion, see JIRA-512") void processesLargeBatch() { /* ... */ } } ``` - On a **method**: only that test is skipped. - On a **class**: *every* `@Test` in that class is skipped. ## The reason string `@Disabled` accepts an optional `String` argument - the **reason**. It is technically optional, but in practice you should always supply it. JUnit prints the reason in the test report, so anyone reading the results understands *why* the test is off and what would need to happen to turn it back on. A bare `@Disabled` with no reason becomes a mystery that lingers in the codebase. ## History: @Disabled vs @Ignore In **JUnit 4** (the previous major version) the equivalent annotation was `@Ignore`. JUnit 5 renamed it to `@Disabled` and moved it into the `org.junit.jupiter.api` package. If you see `@Ignore` you are looking at older JUnit 4 code. Functionally they play the same role: skip this test. ## When (not) to use it Use `@Disabled` to temporarily park a test that is broken, flaky, or waiting on an external fix - always with a reason and ideally a tracking ticket. Avoid leaving tests disabled forever; a permanently disabled test gives a false sense of coverage. For tests that should only run under certain *conditions* (a particular OS, Java version, or environment), prefer the **conditional** annotations like `@EnabledOnOs` / `@DisabledOnOs` instead of unconditional `@Disabled`, because those re-enable themselves automatically when the condition is met.

  • What was the equivalent annotation in JUnit 4?
    @Ignore. JUnit 5 renamed it to @Disabled and moved it to the org.junit.jupiter.api package.
  • Does a disabled test count as passing?
    No. It is reported separately as 'skipped' - it is neither a pass nor a fail, so it does not contribute real coverage.

saying these in an interview costs you the question

  • Thinking @Disabled makes the test pass - it is skipped, not passed
  • Importing JUnit 4's @Ignore instead of org.junit.jupiter.api.Disabled in a JUnit 5 codebase
  • Leaving @Disabled with no reason string
  • Believing @Disabled on a class only disables the first method (it disables all of them)

context

open as a page

Why does @Disabled take an optional reason string, and what is the cost of omitting it?

level: juniorimportance: should knowfreq 45%

basics

~10 s

The reason string explains why the test is turned off. JUnit prints it in the report. Without it, nobody knows why the test is disabled or when it is safe to turn back on.

open as a page

Walk through JUnit 5's conditional execution annotations - @EnabledOnOs, @EnabledIfSystemProperty, @EnabledIfEnvironmentVariable, @EnabledIf - and how each decides whether a test runs.

level: middleimportance: should knowfreq 48%

basics

~20 s

These annotations turn a test on or off based on a condition: the operating system (@EnabledOnOs), a JVM system property (@EnabledIfSystemProperty), an OS environment variable (@EnabledIfEnvironmentVariable), or a custom boolean method (@EnabledIf). Each has a @Disabled... twin that does the opposite.

open as a page

When should you use a conditional annotation like @DisabledOnOs or @EnabledOnOs instead of an unconditional @Disabled?

level: middleimportance: should knowfreq 55%

basics

~20 s

Use @Disabled when a test is just broken or parked. Use conditional annotations like @EnabledOnOs(WINDOWS) or @DisabledOnOs(MAC) when the test should run only under a real condition - a specific OS, Java version, or environment - so it re-enables itself automatically when that condition holds.

open as a page

How does a disabled test interact with lifecycle callbacks, fixtures, and test reporting, and what risks come with accumulating disabled tests at scale?

level: seniorimportance: nice to knowfreq 30%

basics

~20 s

A disabled test is skipped entirely - its body and its @BeforeEach/@AfterEach for that test do not run, though class-level setup may still happen. It shows as 'skipped', not passed. Lots of disabled tests quietly remove coverage, so track and prune them.

open as a page