Share
Embed
Transcript
36 slides
-
Christian Stein • Software developer @ MICROMATA Kassel/Bonn • JUnit
5 core team member since 2017 • Github: https://github.com/sormuras • Twitter: @sormuras -
Marc Philipp • Staff Software Engineer @ in Karlsruhe •
JUnit Maintainer since 2012 • Twitter: @marcphilipp • Web: http://www.marcphilipp.de -
Meta Annotations Annotations can be combined to enable re-use:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Tag("integration") @Test public @interface IntegrationTest {} Usage: @IntegrationTest void test() {} Equivalent: @Tag("integration") @Test void 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); })); } -
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 -
–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 -
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 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 -
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 -
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 } -
IDE Support • IntelliJ supports JUnit 5 ≥ M2 since
2016.2 • Eclipse support is available on Eclipse Marketplace: https://marketplace.eclipse.org/content/junit-5-support- beta-oxygen Will be integrated without requiring any additional work in Oxygen.1a • Interim solution for other IDEs: JUnitPlatform Runner -
Build Tool Support • 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 -
Extension Registration • Declarative: Annotate your test classes or methods
with @ExtendWith to register extensions • Supports an arbitrary number of extensions at the same time • May be used as a meta-annotation • Global: Opt-in support for registration via ServiceLoader -
Extension Points • Conditional Test Execution • ExecutionCondition • 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, test instance lifecycle management, and minor API changes ✔ • 5.0 M6 (July 2017): Java 9 compatibility, validation (e.g. tag syntax), and bug fixes ✔ • 5.0 RC1, RC2, RC3 (July/August 2017): bug fixes and documentation improvements before GA. ✔ • 5.0 GA (this week, really!): First general availability release • 5.1 (October?): additional features -
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/