Table of Contents |
---|
New useful functionality will be added:1.
...
Code Block |
---|
public void shouldRaiseAnException () throws Exception { Assertions.assertThrows(Exception.class, () -> { //... }); } |
...
Code Block |
---|
@Test(expected = Exception.class) |
...
...
Code Block |
---|
@Test(timeout = 1) public void shouldFailBecauseTimeout () throws InterruptedException { Thread.sleep(10); } @Test public void shouldFailBecauseTimeout () throws InterruptedException { Assertions.assertTimeout(Duration.ofMillis(1), () -> Thread.sleep(10)); } |
...
Now , it is possible to write lambdas directly from Assert:
Code Block |
---|
@Test public void shouldFailBecauseTheNumbersAreNotEqual_lazyEvaluation () { Assertions.assertTrue( 2 == 3, () -> "Numbers " + 2 + " and " + 3 + " are not equal!"); } @Test public void shouldAssertAllTheGroup () { List<Integer> list = Arrays.asList(1, 2, 4); Assertions.assertAll("List is not incremental", () -> Assertions.assertEquals(list.get(0).intValue(), 1), () -> Assertions.assertEquals(list.get(1).intValue(), 2), () -> Assertions.assertEquals(list.get(2).intValue(), 3)); } |
4. Assumption. Tests will be executed under conditions:
Code Block |
---|
@Test public void whenEnvironmentIsWeb_thenUrlsShouldStartWithHttp () { assumingThat("WEB".equals(System.getenv("ENV")), () -> { assertTrue("http".startsWith(address)); }); } |
...
...
Code Block |
---|
@RepeatedTest(value = 3, name = "Custom name {currentRepetition}/{totalRepetitions}") void repeatedTestWithCustomDisplayName (TestInfo testInfo){ assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2"); } |
...
...
Code Block |
---|
@ParameterizedTest
@ValueSource(strings = {"Hello", "JUnit"})
void withValueSource (String word){
assertNotNull(word);
} |
Can contain one @BeforeEach method, and one @AfterEach method, but because Java doesn’t allow static members in inner classes, the @BeforeAll and @AfterAll methods don’t work by default.
Code Block |
---|
class JUnit5NestedExampleTest { ... @Nested @DisplayName("Tests in the nested class A") class A { ... @Test @DisplayName("Example test for method A") void sampleTestForMethodA() { //test logic } @Nested @DisplayName("Another nested test class") class B { //test logic } } |
...
} |
Extensions model allows third parties to extend JUnit with their own additions. It is useful when a developer wants to use some features that absent in default JUnit version.
Now five main types of extension points can be used: test instance post-processing, conditional test execution, life-cycle callback, parameter resolution, exception handling.
Code Block |
---|
@ExtendWith(BenchmarkExtension.class)
public @interface Benchmark { ... }
public class BenchmarkExtension implements
BeforeAllCallback, BeforeTestExecutionCallback,
AfterTestExecutionCallback, AfterAllCallback { /* extension logic */}
|
An extension will be executed only if a class marked the corresponding annotation. For detailed information, please take a look at the tutorial.
Junit5 allows the next annotations in interfaces:
And the classes that implement these interface will inherit the test cases.
5 version allows to define custom annotations that act as conditions to determine whether a test should be run or not. It is necessary to create annotation for condition
Code Block |
---|
@Target({ ElementType.METHOD })
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(DisabledOnEnvironmentCondition.class)
public @interface DisabledOnEnvironment {
String[] value();
} |
And class that implements the appropriate interface and override the evaluate() method
Code Block |
---|
@Override
public ConditionEvaluationResult evaluate(TestExtensionContext context) {
// evaluation logic
} |
Now we can add annotation on the test method
Code Block |
---|
@Test
@DisabledOnEnvironment({"dev", "prod"})
void testFail() {
fail("this test fails");
} |
Now it becomes available to define parameters for test constructors and methods and use dependency injection for them. With ParameterResolver class we can resolve parameters in runtime.
At the time of this writing there are 3 built-in parameter resolvers: TestInfo, RepetitionInfo, TestReporter. Example for one of them:
Code Block |
---|
@Test
@DisplayName("Test Get Users")
public void testGetUsersNumberWithInfo(TestInfo testInfo) {
// test logic.
logger.info("Running test method:" + testInfo.getTestMethod().get().getName());
} |
Migration from JUnit 4 to 5 is not so difficult, as backward compatibility is available.
The new features of JUnit 5 can improve Apache Ignite development process and make testing more effectively. Moreover, JUnit 5 has totally backward compatibility with 4 version (it is achievable with JUpiter module).
Tests can be launched under JUnit5. Usage of JUnit 5 annotations becomes available, for example, @RepeatedTest
There are no additional fails on TeamCity.
All modules satisfy the previous two criteria
The community is informed about the migration to 5 and benefits of the newest version.
...
...
...
Actualize JUnit3TestLegacyAssert class: rename it, update documentation. Replacement inheritance to imports is not appropriate here as it leads to changes of all test classes. Moreover, during migration to the next JUnit versions, problem with changing all test classes will arrise again and in new test classes developer should make import manually.
In JUnit3TestLegacySupport:
Futhermore, GridAbstractTest and GridCommonAbstractTest refactoring necessity should be investigated. Check ability to turn some instance methods to static methods. It was mentioned in the conversation on dev-list.
...