JUnit 5中org.junit.Test与org.junit.jupiter.api.Test的差异问询
Key Differences Between
org.junit.Test (JUnit 4) and org.junit.jupiter.api.Test (JUnit 5 Jupiter) Great question—this is one of the first hurdles developers face when transitioning from JUnit 4 to JUnit 5. Let’s break down the critical distinctions between these two annotations:
1. Package & Core Purpose
org.junit.Testis the original test annotation from JUnit 4. In JUnit 5, it’s only supported via the JUnit Vintage module, which exists to run legacy JUnit 4 tests alongside JUnit 5.org.junit.jupiter.api.Testis the modern replacement, designed explicitly for JUnit Jupiter (the core testing framework of JUnit 5). It’s the annotation you should use for all new test code.
2. Annotation Parameters
JUnit 4’s @Test included built-in parameters for common test behaviors, but JUnit 5 replaced these with more flexible assertion methods and extensions:
JUnit 4 Example
// Expected exception @Test(expected = IllegalArgumentException.class) public void invalidInputThrowsException() { doSomethingInvalid(); } // Timeout @Test(timeout = 1000) // Fails if test takes longer than 1 second public void testWithTimeout() { slowOperation(); }
JUnit 5 Equivalent
// Expected exception (using assertions) @Test public void invalidInputThrowsException() { assertThrows(IllegalArgumentException.class, () -> doSomethingInvalid()); } // Timeout (using assertions) @Test public void testWithTimeout() { assertTimeout(Duration.ofSeconds(1), () -> slowOperation()); }
This shift makes test logic more readable and integrates better with modern Java features like lambdas.
3. Method Signature Flexibility
JUnit 4 imposed strict rules on test methods, while JUnit 5 relaxes these for greater flexibility:
- JUnit 4: Test methods must be
public void, have no parameters, and cannot return a value. - JUnit 5: Test methods can:
- Be non-public (though
publicis still acceptable) - Accept parameters (e.g.,
TestInfo,TestReporter, or custom types via extensions) - Return values like
CompletableFuture<Void>for asynchronous testing, orStream<Arguments>(when combined with@ParameterizedTest)
- Be non-public (though
Example of a JUnit 5 test with parameters:
@Test public void testWithTestInfo(TestInfo testInfo) { System.out.println("Running test: " + testInfo.getDisplayName()); }
4. Extension & Meta-Annotation Support
- JUnit 4: Used a combination of runners (
@RunWith) and rules (@Rule) to extend test behavior. The@Testannotation itself wasn’t designed for meta-annotation reuse. - JUnit 5: Leverages a powerful extension model via
@ExtendWith. Additionally,@Testis a meta-annotation, meaning you can create custom composed annotations to reuse test configurations. For example:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Test @Tag("integration") @ExtendWith(DatabaseExtension.class) public @interface IntegrationTest {} // Usage @IntegrationTest public void databaseIntegrationTest() { // Runs with all the settings from @IntegrationTest }
5. Tagging & Filtering
JUnit 5 introduced @Tag to categorize tests, replacing JUnit 4’s @Category:
- JUnit 4:
@Category(IntegrationTests.class) - JUnit 5:
@Tag("integration")
Tags are simpler to use and support more flexible filtering during test execution (e.g., running only unit tests or only integration tests).
Summary
- Use
org.junit.jupiter.api.Testfor all new JUnit 5 tests—it’s more flexible, integrates with modern Java, and supports JUnit 5’s full feature set. - Use
org.junit.Testonly when maintaining legacy JUnit 4 code, or when using JUnit Vintage to run old tests in a JUnit 5 environment.
内容的提问来源于stack exchange,提问作者Nikolas
相关产品推荐
相关产品推荐

