The @Ignore Annotation

@Ignore is a JUnit 4 annotation that temporarily prevents a test method or test class from running. The test remains in the source code and is still discovered by the test runner, but it is reported as ignored rather than passed or failed. This makes @Ignore useful when a test depends on an unavailable service, a known defect has not yet been fixed, or a feature is still under development.
The annotation is located in the org.junit package and supports both methods and types:

package org.junit;

import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD, ElementType.TYPE})
@Documented
public @interface Ignore {
    String value() default "";
}

The important parts are:

  • RUNTIME retention allows the JUnit runner to inspect the annotation while tests are being executed.
  • METHOD and TYPE targets allow the annotation to be placed on either an individual test method or an entire test class.
  • value() is an optional message that explains why the test is being ignored.

Although the reason is optional, it should normally be included. A clear message helps other developers understand whether the test is waiting for a deployment, blocked by a defect, or temporarily incompatible with the current environment.

Ignoring a single test method

To skip one method, apply @Ignore alongside @Test:

import org.junit.Ignore;
import org.junit.Test;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.fail;

public class UserServiceTest {

    @Test
    public void createsUser() {
        assertEquals("alice", "alice");
    }

    @Ignore("Waiting for the user profile API integration")
    @Test
    public void updatesUser() {
        fail("This method must not execute while it is ignored");
    }
}

When the test suite runs:

  • createsUser() is executed normally.
  • updatesUser() is reported as ignored.
  • The body of updatesUser() is never entered, so its assertions cannot fail.

The order of @Ignore and @Test does not matter. Both annotations are visible to JUnit, and either can appear first.

Ignoring an entire test class

Applying @Ignore to a class excludes all of its test methods:

import org.junit.Ignore;
import org.junit.Test;

import static org.junit.Assert.fail;

@Ignore("Migration tests are disabled until schema version 2 is deployed")
public class LegacySchemaMigrationTest {

    @Test
    public void migratesUsers() {
        fail("This ignored test should not execute");
    }

    @Test
    public void migratesOrders() {
        fail("This ignored test should not execute");
    }
}

Class-level @Ignore is useful when a whole subsystem is unavailable or when every test in a class depends on the same external condition. It is generally better than adding the annotation to every method separately.

Why the reason matters

An empty annotation is valid:

@Ignore
@Test
public void pendingTest() {
    // ...
}

However, an unexplained ignored test creates uncertainty. Someone reviewing the build may not know whether the test is obsolete, broken, or waiting for a specific change. A descriptive reason turns the annotation into useful project documentation:

@Ignore("Blocked by API-142; enable after the new gateway is deployed")
@Test
public void synchronizesCustomerAccounts() {
    // ...
}

Good reasons are specific and actionable. They may include:

  • The missing dependency or environment
  • The defect or ticket being tracked
  • The condition that must be met before re-enabling the test
  • A temporary migration or deployment deadline

For example, @Ignore("Waiting for OAuth sandbox credentials") communicates much more than @Ignore.

Ignored tests are not passing tests

An ignored test has not verified the behavior of the application. JUnit skips its body, so no assertion inside it contributes evidence that the code works.

This distinction matters in continuous integration. A build report may show a mixture of:

  • Passed tests, whose assertions succeeded
  • Failed tests, whose assertions did not hold
  • Ignored tests, which were deliberately excluded from execution

Some build tools also enforce limits on ignored or skipped tests. If a project requires all tests to run, a growing ignored count may cause the build to fail even when there are no ordinary test failures. Teams should therefore review ignored tests regularly rather than treating them as harmless.

When to use @Ignore

@Ignore is most appropriate for temporary exclusions, such as:

  • A test that requires a service that is not yet available
  • A test blocked by a known, tracked defect
  • A feature that is under active development
  • A suite waiting for infrastructure or schema changes
  • A flaky test temporarily removed while its root cause is investigated

It should not be used as a permanent substitute for deleting or refactoring an obsolete test. Over time, unexplained or outdated ignored tests can hide regressions and make the suite less trustworthy.

The annotation should also be kept as narrow as possible. If only one scenario in a test is blocked, the rest of the method may still be valuable. In JUnit 4, a conditional assumption can sometimes express that situation more precisely:

import org.junit.Assume;
import org.junit.Test;

import static org.junit.Assert.assertNotNull;

public class FeatureFlagTest {

    @Test
    public void readsNewProfileFormat() {
        Assume.assumeTrue("New profile format is not enabled",
                FeatureFlags.isEnabled("new-profile-format"));

        assertNotNull(new ProfileClient().loadCurrentUser());
    }
}

Here, the test runs when its required condition is available and is skipped when that condition is missing. This differs from @Ignore, which always excludes the annotated method or class.

Practical guidelines

When using @Ignore, follow a few simple practices:

  • Always provide a reason unless the exclusion is immediately obvious.
  • Reference a ticket or issue when the test is blocked by a defect.
  • Keep exclusions temporary and remove the annotation as soon as the condition is resolved.
  • Prefer method-level annotations when the rest of the class remains testable.
  • Review ignored counts in CI to prevent exclusions from accumulating unnoticed.
  • Avoid ignoring a test solely because it fails; investigate and fix the underlying issue instead.

Finally, @Ignore is specific to JUnit 4. JUnit 5 uses the separate @Disabled annotation from org.junit.jupiter.api. Mixing the two versions can lead to compilation errors or an ignored test that the active runner does not recognize.