Skip to content
On this page

Conditional Testing

When running tests, sometimes we need to exclude certain @Test methods from execution. In such cases, we can mark them with @Disabled:

java
@Disabled
@Test
void testBug101() {
    // This test will not run
}

Why not simply comment out the @Test annotation? By commenting it out, JUnit won't recognize it as a test method. However, by adding @Disabled, JUnit still identifies it as a test method but temporarily skips its execution. It will appear in the test results as:

Tests run: 68, Failures: 2, Errors: 0, Skipped: 5

Annotations like @Disabled are known as Conditional Tests. JUnit uses various conditional annotations to decide whether to run the current @Test method based on different conditions.

Example

Let's look at an example:

java
public class Config {
    public String getConfigFile(String filename) {
        String os = System.getProperty("os.name").toLowerCase();
        if (os.contains("win")) {
            return "C:\\" + filename;
        }
        if (os.contains("mac") || os.contains("linux") || os.contains("unix")) {
            return "/usr/local/" + filename;
        }
        throw new UnsupportedOperationException();
    }
}

We want to test the getConfigFile() method. However, the code paths differ between Windows and Linux/Mac systems. Therefore, we create two test methods: one that runs only on Windows and another that runs only on Mac/Linux.

java
@Test
void testWindows() {
    assertEquals("C:\\test.ini", config.getConfigFile("test.ini"));
}

@Test
void testLinuxAndMac() {
    assertEquals("/usr/local/test.cfg", config.getConfigFile("test.cfg"));
}

To apply conditions, we add the following annotations to the test methods:

java
@Test
@EnabledOnOs(OS.WINDOWS)
void testWindows() {
    assertEquals("C:\\test.ini", config.getConfigFile("test.ini"));
}

@Test
@EnabledOnOs({ OS.LINUX, OS.MAC })
void testLinuxAndMac() {
    assertEquals("/usr/local/test.cfg", config.getConfigFile("test.cfg"));
}

@EnabledOnOs is a conditional test annotation that determines whether a test should run based on the operating system.

Common Conditional Test Annotations

Here are some commonly used conditional test annotations:

  • Skip Tests on Windows: Use @DisabledOnOs(OS.WINDOWS) to exclude tests from running on Windows platforms.

    java
    @Test
    @DisabledOnOs(OS.WINDOWS)
    void testOnNonWindowsOs() {
        // TODO: this test is disabled on Windows
    }
  • Skip Tests on Specific Java Versions: Use @DisabledOnJre(JRE.JAVA_8) to exclude tests from running on Java 8.

    java
    @Test
    @DisabledOnJre(JRE.JAVA_8)
    void testOnJava9OrAbove() {
        // TODO: this test is disabled on Java 8
    }
  • Run Tests Only on 64-bit Systems: Use @EnabledIfSystemProperty to conditionally run tests based on system properties.

    java
    @Test
    @EnabledIfSystemProperty(named = "os.arch", matches = ".*64.*")
    void testOnlyOn64bitSystem() {
        // TODO: this test is only run on 64-bit systems
    }
  • Run Tests Based on Environment Variables: Use @EnabledIfEnvironmentVariable to run tests only when certain environment variables are set.

    java
    @Test
    @EnabledIfEnvironmentVariable(named = "DEBUG", matches = "true")
    void testOnlyOnDebugMode() {
        // TODO: this test is only run when DEBUG=true
    }

When running all tests in JUnit, the results will indicate which tests were skipped. In IDEs, skipped tests are usually marked with a ⊘ symbol.

Summary

Conditional testing allows JUnit to automatically skip certain tests based on specific annotations and conditions:

  • Conditional Tests: Use annotations like @Disabled, @EnabledOnOs, @DisabledOnJre, @EnabledIfSystemProperty, and @EnabledIfEnvironmentVariable to control the execution of test methods based on various criteria.
  • Visibility in Test Results: Skipped tests are clearly indicated in the test results, helping developers understand which tests were not executed and why.

By leveraging conditional testing, you can create more flexible and environment-specific test suites, ensuring that tests run only when appropriate and reducing unnecessary test executions.

Conditional Testing has loaded