junit 5 - contentful uses the junit.jar. renaming a private field should not break anything, right?...

34
JUnit 5

Upload: haxuyen

Post on 20-Apr-2018

220 views

Category:

Documents


5 download

TRANSCRIPT

JUnit 5

Marc Philipp• Senior Software Engineer @ in Germany

• JUnit Maintainer since 2012

• Twitter: @marcphilipp

• Web: http://www.marcphilipp.de

Programming Model

DEMO

https://github.com/marcphilipp/junit5-demo/tree/20170604-heisenbug

Meta AnnotationsAnnotations can be combined to enable re-use:@Target(ElementType.METHOD)@Retention(RetentionPolicy.RUNTIME)@Tag("integration")@Testpublic @interface IntegrationTest {}

Usage: @IntegrationTestvoid test() {}

Equivalent: @Tag("integration")@Testvoid test() {}

@ParameterizedTest Sources• @ValueSource(ints = { 1, 2, 3 })

• @EnumSource(TimeUnit.class)

• @MethodSource(names = "myProviderMethod")

• @CsvSource({ "foo, 1", "bar, 2", "'baz, qux', 3" })

• @CsvFileSource(resources = "/two-column.csv")

• @ArgumentsSource(MyArgumentsProvider.class)

• @YourCustomSource

@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() {/* ... */}

// ... } } }

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

@RepeatedTest

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

Why do we need a new JUnit?

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

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

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

Existing ArchitectureEveryone uses the junit.jar.

Renaming a private field should not break anything, right?

4.11 4.12-beta-1

–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.“

Design Goals for JUnit 5• Modern programming model for writing tests ( Java 8!)

• Powerful extension model with a focus on composability

• API Segregation: Decouple test execution/reporting from test definition

• Compatibility with older releases + migration path

• Modularization + no external dependencies

Modularization

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)

P L A T F O R M

J U P I T E RV I N T A G E P A R T YT H I R D

PL

AT

FO

RM

JUP

ITE

R

VIN

TA

GE

PA

RT

YT

HIR

D

JUnitPlatform Runner for a single class

import org.junit.jupiter.api.Test;

@RunWith(JUnitPlatform.class) public class JupiterTest { @Test void someTest() { // test something } }

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 }

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

Compatibility• Backward compatibility

(junit-vintage-engine) enables gradual migration of tests to Jupiter API

• Forward compatibility (JUnitPlatform Runner) allows test execution with “old” tools

Extensions

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

• Opt-in support for registration via ServiceLoader

DEMO

https://github.com/marcphilipp/junit5-demo/tree/20170604-heisenbug

Extension Points• Conditional Test Execution

• ContainerExecutionCondition

• TestExecutionCondition

• General Purpose

• TestInstancePostProcessor

• ParameterResolver

• TestTemplateInvocationContext-Provider

• Test Lifecycle Callbacks

• BeforeAllCallback

• BeforeEachCallback

• BeforeTestExecutionCallback

• TestExecutionExceptionHandler

• AfterTestExecutionCallback

• AfterEachCallback

• AfterAllCallback

Roadmap• 5.0 M4 (April 2017): parameterized and repeated tests ✔

• 5.0 M5 (June 2017): dynamic containers and minor API changes

• 5.0 M6 (July 2017): Java 9 compatibility, scenario tests, additional extension APIs for JUnit Jupiter

• 5.0 RC1 (July 2017): Last fixes before GA

• 5.0 GA (August 2017): First general availability release

Summary

What’s in it for me?• Modern programming model

• Powerful extension points

• Gentle migration path

• Good tool support

• Flexible platform/plugin architecture

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/

Wanted: Feedback!

Website: http://junit.org/junit5/

Code & Issues: https://github.com/junit-team/junit5/

Twitter:https://twitter.com/junitteam