JUnit is the most used testing framework in Java. Over time, it has evolved to introduce new features and improve flexibility. JUnit 4 was the standard for many years, but JUnit 5 has become the modern choice with a more modular architecture and enhanced functionality. This article explains the key differences between JUnit 4 and JUnit 5, their features and why migrating to JUnit 5 is recommended.
- JUnit 4 (released in 2006) simplified Java testing by introducing annotations like @Test, @Before and @After.
- JUnit 5 (released in 2017) is a major redesign, offering a modular approach, better integration with Java 8+ features and improved extensibility.
Example: Calculator Class
We’ll use a simple Calculator class with two methods: add() and subtract().
public class Calculator {
public int add(int a, int b) {
return a + b;
}
public int subtract(int a, int b) {
return a - b;
}
}
JUnit 5 Test Case Design for Calculator Java Class
import org.junit.jupiter.api.*;
public class CalculatorJUnit5Test {
private Calculator calculator;
@BeforeEach
void setUp() {
calculator = new Calculator();
System.out.println("Setting up for test");
}
@AfterEach
void tearDown() {
calculator = null;
System.out.println("after test");
}
@Test
void testAddition() {
System.out.println("addition test");
assertEquals(4, calculator.add(2, 2));
}
@Test
void testSubtraction() {
System.out.println("subtraction test");
assertEquals(2, calculator.subtract(4, 2));
}
}
JUnit 4 Test Case Design for Calculator Java Class
import org.junit.*;
public class CalculatorJUnit4Test {
private Calculator calculator;
@Before
public void setUp() {
calculator = new Calculator();
System.out.println("Setting up for test");
}
@After
public void tearDown() {
calculator = null;
System.out.println("after test");
}
@Test
public void testAddition() {
System.out.println("addition test");
assertEquals(4, calculator.add(2, 2));
}
@Test
public void testSubtraction() {
System.out.println("subtraction test");
assertEquals(2, calculator.subtract(4, 2));
}
}
Difference between JUnit 5 and JUnit 4
| Topic | JUnit 5 | JUnit 4 |
|---|---|---|
| Architecture | Modular and extensible, supports Java 8 features including lambdas. | Monolithic architecture, limited Java 8 support. |
| Annotations | Introduces new annotations: @BeforeEach, @AfterEach, @BeforeAll, @AfterAll. | Provides older set: @Before, @After, @BeforeClass, @AfterClass. |
| Test Extensions | Supports powerful extension model with @ExtendWith for parameter resolution, post-processing, etc. | Limited extension support; relies on test runners. |
| Parameterized Tests | Built-in support using @ParameterizedTest, @ValueSource, etc. | Requires @RunWith(Parameterized.class). |
| Conditional Test Execution | Provides annotations like @EnabledOnOs, @EnabledIf. | Very limited conditional support. |
| Dynamic Tests | Supports runtime test generation via @TestFactory. | Only static test methods supported. |
| Assertions | More flexible with assertAll, multiple assertions per test. | Basic assertions from org.junit.Assert. |
| Tagging & Filtering | Supports tagging with @Tag for grouping/filtering tests. | Limited tagging support. |
| IDE Support | Growing support in modern IDEs. | Mature support across IDEs. |
| Compatibility | Not backward-compatible with JUnit 4. Migration is required. | Has backward compatibility with JUnit 3. |