You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JUnit 5(Jupiter)中标记单元测试为预期失败?

Answer

Great question! JUnit 5 (Jupiter) doesn’t include a built-in @ExpectedFailure annotation out of the box, but you can fully meet your requirements—running the test, treating failures as passes, and failing the build if the test starts passing—with a couple of straightforward approaches.

Quick Inline Solution (No Custom Code Needed)

You can combine a try-catch block with an explicit fail() call, plus a @Tag to mark the test as an expected failure for clarity in build outputs:

import org.junit.jupiter.api.Tag;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class YourTestClass {

    @Tag("expected-failure")
    @Test
    void testThatCurrentlyFails() {
        try {
            // Your existing test code that currently fails
            yourFailingTestMethod();
            
            // If we reach this line, the test passed unexpectedly—fail the build
            fail("This test was expected to fail, but it passed!");
        } catch (YourExpectedException e) {
            // The test failed as intended—confirm success
            assertTrue(true, "Test failed as expected (this counts as a pass)");
        }
    }
}

How this works:

  • If the test throws your expected exception, it’s treated as a pass.
  • If the test completes without throwing the exception (i.e., it starts working), the fail() call triggers a build failure to alert you.
  • The @Tag("expected-failure") lets build tools (Maven Surefire, Gradle) and test reports clearly flag this as a non-standard test.

Elegant Custom Annotation & Extension

For cleaner test code, create a custom @ExpectedFailure annotation paired with a JUnit Extension to handle the logic automatically:

Step 1: Define the Custom Annotation

import org.junit.jupiter.api.extension.ExtendWith;
import java.lang.annotation.*;

@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(ExpectedFailureExtension.class)
public @interface ExpectedFailure {
    String value() default "This test is expected to fail";
}

Step 2: Implement the Extension

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.extension.*;

public class ExpectedFailureExtension implements TestExecutionExceptionHandler, AfterTestExecutionCallback {

    @Override
    public void handleTestExecutionException(ExtensionContext context, Throwable throwable) throws Throwable {
        // Log that the test failed as intended (optional but helpful for build logs)
        System.out.printf("[EXPECTED FAILURE] %s: %s%n", 
            context.getDisplayName(), throwable.getMessage());
        // Do not rethrow the exception—treat this as a pass
    }

    @Override
    public void afterTestExecution(ExtensionContext context) throws Exception {
        // If no exception was thrown, the test passed unexpectedly—fail the build
        if (!context.getExecutionException().isPresent()) {
            String message = context.getDisplayName() + " was expected to fail, but passed successfully!";
            Assertions.fail(message);
        }
    }
}

Step 3: Use the Annotation in Your Tests

import org.junit.jupiter.api.Test;

public class YourTestClass {

    @ExpectedFailure("Fails due to unimplemented feature XYZ—remove this annotation once fixed")
    @Test
    void testThatCurrentlyFails() {
        // Your existing test code (no extra try-catch needed!)
        yourFailingTestMethod();
    }
}

How this works:

  • The extension automatically catches exceptions from the test and treats them as passes.
  • If the test completes without exceptions, it triggers a build failure with a clear message.
  • The annotation’s value lets you add context (e.g., why the test is expected to fail) for future reference.

Build Output Clarity

Both approaches work seamlessly with build tools like Maven and Gradle. The @Tag or custom annotation will show up in test reports, so you can easily distinguish expected failures from genuine test failures in your build logs.

内容的提问来源于stack exchange,提问作者Troy Daniels

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 18:29:10