Upgrade to Pro — share decks privately, control downloads, hide ads and more …

JUnit 5: Testing Framework für Java und Plattfo...

Marc Philipp
February 20, 2017

JUnit 5: Testing Framework für Java und Plattform für die JVM

Marc Philipp

February 20, 2017
Tweet

More Decks by Marc Philipp

Other Decks in Programming

Transcript

  1. Marc Philipp • Senior Software Engineer @ Karlsruhe • JUnit

    Maintainer seit 2012 • Twitter: @marcphilipp • Web: http://www.marcphilipp.de
  2. Meta Annotations Annotationen können miteinander kombiniert werden:
 
 @Target(ElementType.METHOD)
 @Retention(RetentionPolicy.RUNTIME)


    @Tag("fast")
 @Test
 public @interface FastTest {} Verwendung:
 
 @FastTest
 void test() {}
 Entspricht:
 
 @Tag("fast")
 @Test
 void test() {}
  3. @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() {/* ... */} // ... } } }
  4. Dynamic Tests @TestFactory Stream<DynamicTest> dynamicTestsFromStream() { return IntStream.iterate(0, n ->

    n + 2).limit(11) .mapToObj(n -> dynamicTest("test" + n, () -> { assertTrue(n % 2 == 0); })); }
  5. Runner • Sehr mächtig: Komplette Ausführung kann angepasst werden •

    Aber: Es kann nur einen Runner pro Testklasse geben! • Runner lassen sich nicht kombinieren, z. B.
 SpringJUnit4ClassRunner + Parameterized
  6. Rules • Neuer Erweiterungsmechanismus seit JUnit 4.7 • Wrapper um

    Ausführung eines Tests (@Rule) oder einer Testklasse (@ClassRule) • Sehr gute Kombinierbarkeit • Aber: Oft nicht mächtig genug, um auf die Testausführung auf unterschiedlichen Ebenen zu beeinflussen (z.B. Spring)
  7. Separation of Concerns 1. Eine API um Tests zu schreiben

    (Jupiter API) 2. Erweiterbarer Mechanismus zum Auffinden und Ausführen von Tests (Test Engine SPI) 3. Eine API für die Testausführung durch Tools (Launcher API)
  8. 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
  9. 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
  10. Testausführung • IDEs: • IntelliJ unterstützt JUnit 5 ≥ M2

    seit 2016.2 • Eclipse-Unterstützung gibt es auf einem Branch • Übergangslösung für andere IDEs: JUnitPlatform Runner • Gradle/Maven: Plugin/Provider verfügbar • siehe https://github.com/junit-team/junit5-samples • Manuell: ConsoleLauncher
  11. Kompatibilität • Rückwärtskompatibilität (junit-vintage-engine) ermöglicht schrittweise Migration auf Jupiter •

    Vorwärtskompatibilität (JUnitPlatform Runner) ermöglicht Testausführung mit “alten” Tools
  12. Registrierung über @ExtendWith • Eine (!) Annotation zur Registrierung von

    Extensions • An Testklassen oder -methoden • Gleichzeitige Registrierung beliebig vieler Extensions wird unterstützt • Kann auch als Meta-Annotation verwendet werden!
  13. Extension Points • Conditional Test Execution • ContainerExecutionCondition • TestExecutionCondition

    • General Purpose • TestInstancePostProcessor • TestExecutionExceptionHandler • ParameterResolver • Test Lifecycle Callbacks • BeforeAllCallback • BeforeEachCallback • BeforeTestExecutionCallback • AfterTestExecutionCallback • AfterEachCallback • AfterAllCallback
  14. Eine Extension — Mehrere Extension Points • Eine Extension kann

    mehrere Extension- Interfaces implementieren • E.g. BeforeEachCallback und AfterEachCallback
  15. ParameterResolver • Konstruktoren und Testmethoden können nun Parameter haben •

    Registrierte ParameterResolvers sind dafür zuständig, die Parameter aufzulösen • Beispiele: TestInfoParameterResolver, TestReporterParameterResolver, MockitoExtension
  16. Third-party Extensions (Auswahl) • SpringExtension
 https://github.com/sbrannen/spring-test-junit5 • Core Spring TestContext

    Framework Features • Constructor und Method Injection via @Autowired, @Qualifier, @Value • upREST
 https://github.com/selesy/uprest • Declarative Tests für REST APIs
  17. Roadmap to GA • 5.0.0-M4 (März 2017): Parametrisierte Tests •

    5.0.0-M5 (Juni 2017): Kompatibilität mit Java 9 • 5.0.0-RC1 (Juli 2017): Letzte Änderungen vor GA • 5.0.0 (August 2017): GA
  18. M4: @TestTemplate class MyTest { @TestTemplate @ExtendWith(MyTestTemplateInvocationContextProvider.class) void testTemplate() {

    // test something } } class MyTestTemplateInvocationContextProvider implements TestTemplateInvocationContextProvider { @Override public Iterator<TestTemplateInvocationContext> provide(ContainerExtensionContext context) { return singleton(new MyTestTemplateInvocationContext()).iterator(); } } class MyTestTemplateInvocationContext implements TestTemplateInvocationContext { @Override public String getDisplayName(int invocationIndex) { return "[" + invocationIndex + "]"; } @Override public List<Extension> getAdditionalExtensions() { return asList(new MyParameterResolver(), new MyTestInstancePostProcessor()); } }
  19. M4: @ParameterizedTest class ParameterizedTests { @ParameterizedTest @StringSource({ "foo, 1", "bar,

    2" }) void testWithParametersFromAnnotation(String parameter, int i) { // test something } @ParameterizedTest @MethodSource("providerMethod") void testWithParametersFromMethods(String parameter) { } static Iterable<String> providerMethod() { return asList("foo", "bar"); } @ParameterizedTest @FileSource("foo.csv") @FileSource("bar.csv") void testWithParametersFromFile(String parameter) { } }