Summarize the relationship among Junit4 Junit5 and Jupiter
- 2021-10-13 07:29:50
- OfStack
Junit5
At present, the most popular unit testing framework in Java field-JUnit
The latest version of Junit, JUnit5, was released in 2017.
Junit 5 = Junit Platform + Junit Jupiter + Junit Vintage
Junit Platform: Junit Platform is the basis for starting the test framework on JVM, which not only supports the self-made test engine of Junit, but also can access other test engines.
Junit Jupiter: Junit Jupiter provides a new programming model for JUnit5 and is at the heart of the new features of JUnit5. It contains a test engine to run on Junit Platform.
Junit Vintage: Since JUnit has been developed for many years, in order to take care of old projects, JUnit Vintage provides a test engine compatible with JUnit4. x and Junit3. x.
Dependency
Junit4
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
Currently dependency will introduce packages for junit: 4.12 and hamcrest-core: 1.3
Junit vintage engine
<dependency>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
At present, dependency will introduce unit: 4.13, apiguardian-api: 1.1. 0, hamcrest-core: 1.3, junit-platform-commons: 1.6. 2.
Packages for junit-platform-engine: 1.6. 2, junit-vintage-engine: 5.6. 2, opentest4j: 1.2. 0
Jupiter
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.6.2</version>
<scope>test</scope>
</dependency>
At present, dependency will introduce packages of apiguardian-api: 1.1. 0, junit-Jupiter-api: 5.6. 2, junit-platform-commons: 1.6. 2, opentest4j: 1.2. 0
Annotation Difference between Junit4 and Junit5
Junit5 | Junit4 | 说明 |
---|---|---|
@Test | @Test | 被注解的方法是1个测试方法。与 JUnit 4 相同。 |
@BeforeAll | @BeforeClass | 被注解的(静态)方法将在当前类中的所有 @Test 方法前执行1次。 |
@BeforeEach | @Before | 被注解的方法将在当前类中的每个 @Test 方法前执行。 |
@AfterEach | @After | 被注解的方法将在当前类中的每个 @Test 方法后执行。 |
@AfterAll | @AfterClass | 被注解的(静态)方法将在当前类中的所有 @Test 方法后执行1次。 |
@Disabled | @Ignore | 被注解的方法不会执行(将被跳过),但会报告为已执行 |
@ Test in Junit4 is import org. junit. Test;
The @ Test in Jupiter is import org. junit. jupiter. api. Test;
Assertion
There are standard assertions in Junit4 and Junit5
断言方法 | 说明 |
---|---|
assertEquals(expected, actual) | 如果 expected 不等于 actual ,则断言失败。 |
assertFalse(booleanExpression) | 如果 booleanExpression 不是 false ,则断言失败。 |
assertNull(actual) | 如果 actual 不是 null ,则断言失败。 |
assertNotNull(actual) | 如果 actual 是 null ,则断言失败。 |
assertTrue(booleanExpression) | 如果 booleanExpression 不是 true ,则断言失败。 |
If any assertion in Junit4 fails, the test will fail at that location, meaning that no other assertions will be executed. For example, should_test_every_test in StudentTest.
@Test
public void should_test_every_test() {
//given when
int expected = 6;
int actual = 10 - 4;
Object nullValue = null;
//then
assertEquals(expected, actual);
assertFalse(true);
assertNull(nullValue);
assertTrue(false);
}
What if you want all assertions to be executed, even if one or more assertions fail?
You can use the aseertAll method provided in Jupiter
@Test
@DisplayName("test assertAll")
void should_test_every_test() {
//given when
int expected = 4;
int actual = 2 + 2;
Object nullValue = null;
//then
assertAll(
"Assert All of these",
() -> assertEquals(expected, actual),
() -> assertFalse(nullValue == null),
() -> assertNull(nullValue),
() -> assertNotNull("Hello Word!"),
() -> assertTrue(nullValue != null));
}
@DisplayName
You can add @ DisplayName annotations to classes and methods. This name is used when generating reports, which makes it easier to describe the purpose of tests and track failures
After running the unit test, click the following location to generate the html report
The unit test report generated by Student is Test Results-StudentTest. html
The unit test report generated by StudentJupiterTest is Test Results-StudentJupiterTest. html
Check anomaly
Junit4 provides @ Test (expected = Exception. class) to verify exceptions, but the disadvantage of this approach is that when two different services throw the same traffic exception,
However, only when message is different, it cannot be accurately verified.
@Test(expected = BusinessException.class)
public void should_throw_business_exception_when_student_name_length_more_than_10() {
//given when
StudentCommand.builder()
.name(RandomStringUtils.randomAlphanumeric(11))
.build();
}
@Test(expected = BusinessException.class)
public void should_throw_business_exception_when_student_description_length_more_than_20() {
//given when
StudentCommand.builder()
.name(RandomStringUtils.randomAlphanumeric(9))
.description(RandomStringUtils.randomAlphanumeric(21))
.build();
}
Of course, it is also possible to judge message by catching exceptions, but this method is not very elegant.
@Test
public void should_validate_message_when_student_name_length_more_than_10() {
//given when
try {
StudentCommand.builder()
.name(RandomStringUtils.randomAlphanumeric(11))
.build();
} catch (BusinessException e) {
assertEquals(e.getMessage(), "The length of student name exceed 10 chars.");
}
}
Jupiter provides a new verification method, Assertions. assertThrows, and in version 4.13 of Junit, Asserts. assertThrows also provides similar functions
@Test
@DisplayName("It tests the length of student name should less than 10 chars")
void should_throw_business_exception_when_student_name_length_more_than_10() {
//given when
BusinessException businessException = Assertions.assertThrows(BusinessException.class, this::buildStudentName);
//then
assertEquals(businessException.getMessage(), "The length of student name exceed 10 chars.");
}
private void buildStudentName() {
StudentCommand.builder()
.name(RandomStringUtils.randomAlphanumeric(11))
.build();
}
@Test
@DisplayName("It tests the length of student description should less than 20 chars")
void should_throw_business_exception_when_student_description_length_more_than_20() {
//given when
BusinessException businessException = Assertions.assertThrows(BusinessException.class, this::buildStudentDescription);
//then
assertEquals(businessException.getMessage(), "The length of student name exceed 20 chars.");
}
private void buildStudentDescription() {
StudentCommand.builder()
.description(RandomStringUtils.randomAlphanumeric(21))
.build();
}