ID | IEP-30 |
Author | Ivan Fedotov |
Sponsor | |
Created | 21.02.2018 |
Status | DRAFT |
New useful functionality will be added:
public void shouldRaiseAnException () throws Exception { Assertions.assertThrows(Exception.class, () -> { //... }); }
In JUnit4:
@Test(expected = Exception.class)
@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:
@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)); }
Tests will be executed under conditions:
@Test public void whenEnvironmentIsWeb_thenUrlsShouldStartWithHttp () { assumingThat("WEB".equals(System.getenv("ENV")), () -> { assertTrue("http".startsWith(address)); }); }
@RepeatedTest(value = 3, name = "Custom name {currentRepetition}/{totalRepetitions}") void repeatedTestWithCustomDisplayName (TestInfo testInfo){ assertEquals(2, Math.addExact(1, 1), "1 + 1 should equal 2"); }
@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.
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.
@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
@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
@Override public ConditionEvaluationResult evaluate(TestExtensionContext context) { // evaluation logic }
Now we can add annotation on the test method
@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:
@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.
Remove JUnit3TestLegacyAssertclass. Replace inheritance to imports
In JUnit3TestLegacySupport:
Devlist discussion.
Question to JUnit develop team about surefire version.