JUnit 5 is the most widely used testing framework for the Java ecosystem. Unlike its predecessors, JUnit 5 is not a single library but a modular framework composed of several different modules from three different sub-projects:
- JUnit Platform: The foundation for launching testing frameworks on the JVM. It defines the
TestEngineAPI for developing a testing framework that runs on the platform. - JUnit Jupiter: The combination of the new programming model and extension model for writing tests and extensions in JUnit 5. It provides the engine for running Jupiter-based tests.
- JUnit Vintage: Provides a
TestEnginefor running JUnit 3 and JUnit 4 based tests on the platform, ensuring backward compatibility.
Why JUnit 5?
JUnit 5 was redesigned to take advantage of Java 8+ features (like lambda expressions) and to solve the limitations of the “monolithic” architecture of JUnit 4. It provides a more robust extension model, better organization for nested tests, and a powerful engine for parameterized and dynamic testing.
Setup & Getting Started
New to JUnit 5? Start here: JUnit 5 with Gradle & Maven: From Setup to Professional Testing
Core Lifecycle Annotations
These annotations control the flow of your test suite, determining what runs before and after your test methods.
| Annotation | Description |
@Test | Denotes that a method is a test method. Unlike JUnit 4, it does not declare attributes. |
@BeforeEach | The method will execute before each test method in the current class. |
@AfterEach | The method will execute after each test method in the current class. |
@BeforeAll | The method will execute once before all test methods (must be static unless using @TestInstance). |
@AfterAll | The method will execute once after all test methods (must be static). |
Organizing & Displaying Tests
These help in making your test reports more readable and grouping tests together. Read More: Master JUnit 5: How to Organize and Display Your Tests Like a Pro
@DisplayName("Custom Name"): Declares a custom display name for the test class or method.@Nested: Indicates that the annotated class is a non-static nested test class (allows for hierarchical grouping).@Tag("name"): Used to filter tests (similar to Categories in JUnit 4).@Disabled: Used to disable a test class or method (equivalent to@Ignorein JUnit 4).
Advanced Test Types
JUnit 5 introduces powerful ways to run the same test logic with different data or configurations.
@ParameterizedTest: Signal that a test should be run multiple times with different arguments.- Companion annotations:
@ValueSource,@CsvSource,@MethodSource,@EnumSource.
- Companion annotations:
@RepeatedTest(n): Repeats the test a specified number of times.@TestFactory: Denotes a method that is a test factory for dynamic tests (tests generated at runtime).@TestTemplate: Indicates a template for test cases designed to be invoked multiple times depending on the registration of providers.
Conditional Execution
These allow you to run tests only when certain environment conditions are met. Read More: Mastering JUnit 5 Conditional Execution: Build Smarter, Environment-Aware Tests
@EnabledOnOs/@DisabledOnOs: Target specific operating systems (e.g., Windows, macOS, Linux).@EnabledOnJre/@DisabledOnJre: Target specific Java versions.@EnabledIfSystemProperty: Run based on the value of a JVM system property.@EnabledIfEnvironmentVariable: Run based on environment variables.
Extension & Configuration
@ExtendWith: Used to register extensions declaratively (replaces@RunWithand@Rule).@RegisterExtension: Used to register extensions via fields.@TestInstance(Lifecycle.PER_CLASS): Configures the test instance lifecycle (allows@BeforeAllon non-static methods).@TestMethodOrder: Used to configure the execution order of tests (e.g.,Alphanumeric,Random).@Timeout: Used to fail a test if its execution exceeds a given duration.
Migrating to JUnit 6
Ready to upgrade? These guides cover what changed and how to handle common pitfalls during the migration: