JUnit5 New Features Comparison
JUnit 5 is not simply an incremental release of the JUnit framework. It represents a substantial redesign of how Java tests are structured, executed, and extended. For teams that have relied on JUnit 4, the new version brings both familiar concepts and important differences.
Modular Architecture
JUnit 5 is distributed as a set of modules rather than one monolithic artifact.
- JUnit Platform: Handles test discovery, test engine launching, and integrations such as the Console Launcher and build tool support.
- JUnit Jupiter: Provides the modern programming model and test engine for JUnit 5.
- JUnit Vintage: Offers compatibility for older JUnit 3 and 4 tests.
The platform acts as the execution layer. Jupiter serves as the primary API, while Vintage supports legacy tests. This separation allows a single test run to include multiple engines and makes integration with IDEs and build tools more flexible.
Lifecycle Annotations Compared
In JUnit 4, annotations such as @Before, @After, @BeforeClass, and @AfterClass belong to org.junit. JUnit 5 introduces corresponding annotations under org.junit.jupiter.api.
@Beforebecomes@BeforeEach.@Afterbecomes@AfterEach.@BeforeClassbecomes@BeforeAll.@AfterClassbecomes@AfterAll.@Ignorebecomes@Disabled.@Categorybecomes@Tag.@RunWithbecomes@ExtendWith.@Ruleand@ClassRuleare replaced by the extension model or parameter resolution.
JUnit 5 also adds annotations such as @DisplayName, @Nested, @RepeatedTest, and @Timeout.
import org.junit.jupiter.api.*;
class CalculatorTest {
@BeforeAll
static void setUpAll() {
}
@BeforeEach
void setUp() {
}
@Test
@DisplayName("Addition should return the correct sum")
void addition() {
assertEquals(2, 1 + 1);
}
@AfterEach
void tearDown() {
}
@AfterAll
static void tearDownAll() {
}
}
Assertions, Assumptions, and Timeouts
JUnit 5 expands the assertion and assumption libraries. The Assertions class includes new helpers for grouped checks, exception validation, and timeouts.
assertAll: Runs multiple assertions and reports all failures together.assertThrows: Verifies that an exception is thrown.assertTimeoutandassertTimeoutPreemptively: Enforce time limits.assumeTrueandassumingThat: Skip tests when a precondition is false.
@Test
void groupedAssertions() {
assertAll("calculator",
() -> assertEquals(2, 1 + 1),
() -> assertEquals(3,