Slide 1

Slide 1 text

JUnit 5

Slide 2

Slide 2 text

Marc Philipp • Senior Software Engineer @ in Germany • JUnit Maintainer since 2012 • Twitter: @marcphilipp • Web: http://www.marcphilipp.de

Slide 3

Slide 3 text

Programming Model

Slide 4

Slide 4 text

DEMO

Slide 5

Slide 5 text

Meta Annotations Annotations can be combined to enable re-use:
 
 @Target(ElementType.METHOD)
 @Retention(RetentionPolicy.RUNTIME)
 @Tag("fast")
 @Test
 public @interface FastTest {} Usage:
 
 @FastTest
 void test() {}
 Equivalent:
 
 @Tag("fast")
 @Test
 void test() {}

Slide 6

Slide 6 text

@Nested Tests @DisplayName("A stack") class TestingAStackDemo { @Test @DisplayName("is instantiated with new Stack()") void isInstantiatedWithNew() {/* ... */} @Nested @DisplayName("when new") class WhenNew { @BeforeEach void createNewStack() {/* ... */} @Test @DisplayName("is empty") void isEmpty() {/* ... */} // ... @Nested @DisplayName("after pushing an element") class AfterPushing { @BeforeEach void pushAnElement() {/* ... */} @Test @DisplayName("it is no longer empty") void isNotEmpty() {/* ... */} // ... } } }

Slide 7

Slide 7 text

Dynamic Tests @TestFactory Stream dynamicTestsFromStream() { return IntStream.iterate(0, n -> n + 2).limit(100) .mapToObj(n -> dynamicTest("test" + n, () -> { assertTrue(n % 2 == 0); })); }

Slide 8

Slide 8 text

Why do we need a new JUnit?

Slide 9

Slide 9 text

Runner • Very powerful: Almost every aspect of test execution can be changed • But: You can only have one Runner per test class! • You can’t combine Runners, e.g.
 SpringJUnit4ClassRunner + Parameterized

Slide 10

Slide 10 text

Rules • Extension mechanism introduced in JUnit 4.7 • Wraps execution of a test (@Rule) or a test class (@ClassRule) • Designed to be combined — great for simple use cases • But: a single rule cannot be used for method-level and class-level callbacks, no support for instance-level callbacks

Slide 11

Slide 11 text

http://blog.takipi.com/the-top-100-java-libraries-in-2016-after-analyzing-47251-dependencies/

Slide 12

Slide 12 text

Existing Architecture Everyone uses the junit.jar.

Slide 13

Slide 13 text

Renaming a private field should not break anything, right? 4.11 4.12-beta-1

Slide 14

Slide 14 text

–Johannes Link, https://jaxenter.com/crowdfunding-for-junit-lambda-is- underway-119546.html „The success of JUnit as a platform prevents the development of JUnit as a tool.“

Slide 15

Slide 15 text

Modularization

Slide 16

Slide 16 text

Separation of Concerns 1. An API to write tests (Jupiter API) 2. Extensible mechanisms to discover and execute tests (Test Engine SPI) 3. An API for test execution by tools (Launcher API)

Slide 17

Slide 17 text

P L AT F O R M J U P I T E R V I N TA G E P A R T Y T H I R D

Slide 18

Slide 18 text

P L AT F O R M J U P I T E R V I N TA G E P A R T Y T H I R D

Slide 19

Slide 19 text

JUnitPlatform Runner for a single class import org.junit.jupiter.api.Test; @RunWith(JUnitPlatform.class) public class JupiterTest { @Test void someTest() { // test something } }

Slide 20

Slide 20 text

JUnitPlatform Runner in suite mode @RunWith(JUnitPlatform.class) @SelectPackages("com.acme") @IncludeEngines({"junit-jupiter", "junit-vintage"}) public class JUnit4SuiteDemo { // this class can be run using JUnit 4 }

Slide 21

Slide 21 text

Test Execution • IDEs: • IntelliJ supports JUnit 5 ≥ M2 since 2016.2 • Eclipse support is available on a branch (see Instructions).
 Official release slated for Oxygen.1. • Interim solution for other IDEs: JUnitPlatform Runner • Gradle/Maven: Plugin/Provider available • see https://github.com/junit-team/junit5-samples • Manually: ConsoleLauncher

Slide 22

Slide 22 text

Compatibility • Backward compatibility (junit-vintage-engine) enables gradual migration of tests to Jupiter API • Forward compatibility (JUnitPlatform Runner) allows test execution with “old” tools

Slide 23

Slide 23 text

Extensions

Slide 24

Slide 24 text

Registration via @ExtendWith • Annotate your test classes or methods to register extensions • Supports an arbitrary number of extensions at the same time • May be used as a meta-annotation

Slide 25

Slide 25 text

DEMO

Slide 26

Slide 26 text

Extension Points • Conditional Test Execution • ContainerExecutionCondition • TestExecutionCondition • General Purpose • TestInstancePostProcessor • TestExecutionExceptionHandler • ParameterResolver • Test Lifecycle Callbacks • BeforeAllCallback • BeforeEachCallback • BeforeTestExecutionCallback • AfterTestExecutionCallback • AfterEachCallback • AfterAllCallback

Slide 27

Slide 27 text

Roadmap

Slide 28

Slide 28 text

M4: @ParameterizedTest class ParameterizedTests { @ParameterizedTest @CsvSource({ "foo, 1", "bar, 2" }) void testWithParametersFromAnnotation(String parameter, int i) { // test something } @ParameterizedTest @MethodSource(names = "providerMethod") void testWithParametersFromMethods(String parameter) { } static Iterable providerMethod() { return asList("foo", "bar"); } @ParameterizedTest @CsvFileSource(resources = { "foo.csv", "/bar.csv" }) void testWithParametersFromFile(String parameter) { } }

Slide 29

Slide 29 text

M4: @RepeatedTest @RepeatedTest(10) void repeatedTest() { // ... }

Slide 30

Slide 30 text

Roadmap to GA • 5.0.0-M4 (April 2017): Parameterized/RepeatedTests • 5.0.0-M5 (?) (May 2017): Java 9 compatibility • 5.0.0-RC1 (June 2017): Last fixes before GA • 5.0.0 (July 2017): GA

Slide 31

Slide 31 text

Getting Started User Guide:
 http://junit.org/junit5/docs/current/user-guide/ Sample projects for Gradle and Maven:
 https://github.com/junit-team/junit5-samples Javadoc:
 http://junit.org/junit5/docs/current/api/

Slide 32

Slide 32 text

Wanted: Feedback! Website:
 http://junit.org/junit5/ Code & Issues:
 https://github.com/junit-team/junit5/ Twitter:
 https://twitter.com/junitteam