Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

JUnit 5 - from Lambda to Alpha and beyond

2,343 views

Published on

Want to know what the hype surrounding JUnit 5 is all about? Then join this talk by JUnit 5 core committer Sam Brannen to find out!

Since JUnit 4.0 was first released, a lot has happened in the world of Java. Unfortunately, JUnit 4 hasn't kept up with the times. JUnit 5 therefore aims to help shape the future of testing on the JVM, with a focus on Java 8, modularity, extensibility, and a modern programming API for authoring tests in Java.

This presentation will start off by providing attendees an overview of the inspiration for and architecture of JUnit 5, from launchers to test engines. Sam will then take the audience on an example-driven tour of the new programming model, highlighting support for dependency injection via flexible method signatures, conditional test execution, using lambda expressions and method references in assertions and assumptions, and implementing test/before/after methods via interface default methods.

To round off the discussion, Sam will present an overview of the new extension model in JUnit 5, discussing how to author and register extensions for conditional tests, method parameter resolution, lifecycle callbacks, and more.

Published in: Software

JUnit 5 - from Lambda to Alpha and beyond

  1. 1. from Lambda to Alpha and Beyond … Sam Brannen @sam_brannen JUnit
  2. 2. 2 Sam Brannen • Spring and Java Consultant @ • Java Developer for over 17 years • Spring Framework Core Committer since 2007 • Swiss Spring User Group Lead • Trainer & Conference Speaker • JUnit 5 Core Committer since October 2015
  3. 3. 3 Swiftmind Experts in Spring and Enterprise Java Areas of expertise • Spring * • Java EE • Software Architecture • Software Development Where you find us • Zurich, Switzerland • @swiftmind • http://www.swiftmind.com
  4. 4. 4 A Show of Hands…
  5. 5. 5 Agenda • Impetus for Change • JUnit Lambda • Roadmap • JUnit 5 • Feedback • Q&A
  6. 6. 6 Impetus for Change
  7. 7. 7 Why a New Version of JUnit? • JUnit 4.0 was released a decade ago – a lot has changed since then… – testing needs have matured – expectations have grown • Modularity  big ball of mud • Test discovery and execution  tightly coupled • Extensibility  lot of room for improvement • Let’s not forget Java 8
  8. 8. 8 Modularity in JUnit 4 • Sure there are packages – but… there’s only THE junit.jar
  9. 9. 9 JUnit 4 Runner API • Very powerful • In fact, it can do anything • But… you can’t combine Runners • Parameterized + SpringJUnit4ClassRunner  no way
  10. 10. 10 JUnit 4… Rules… are meant to be broken • JUnit 4.7: MethodRule (@Rule) • JUnit 4.9: TestRule (@Rule / @ClassRule) • Great for simple use cases • Can even be combined • But… a single rule can’t be used for method-level and class-level callbacks • Plus… zero support for instance-level callbacks • Case in point: SpringClassRule / SpringMethodRule
  11. 11. 11 JUnit Lambda
  12. 12. 12 Crowdfunding Campaign • Initiated by Johannes Link and Marc Philipp • Later joined by Matthias Merdes, Stefan Bechtold, & Sam Brannen • Ran from July to October 2015 • Raised 53,937 Euros from 474 individuals and companies • 4 companies donated 6 weeks of developer time
  13. 13. 13 Thanks!
  14. 14. 14 The Kick-off Team
  15. 15. 15 Roadmap • Prototype  December 2nd, 2015 • 5.0.0-ALPHA  February 1st, 2016 • 5.0.0-M1  in progress – tentative release end of June 2016 • M2, M3, …  Summer 2016 • RC1, RC2, ...  Fall 2016 • GA  late 2016
  16. 16. 16 JUnit 5
  17. 17. 17 JUnit 5… in a Nutshell • Modular • Extensible • Modern • Forward and backward compatible – JUnit 5 supports JUnit 3.8 and JUnit 4 – Can be run with JUnit 4 • @RunWith(JUnit5.class)
  18. 18. 18 Architecture • Test code depends only on the JUnit 5 API. • IDEs and build tools depend on the Launcher and Engine APIs and can execute tests independent of the testing framework in use.
  19. 19. 19 Modules • junit5-api • junit-launcher • junit-engine-api • junit5-engine • junit4-engine • junit4-runner • junit-commons • junit-console • junit-gradle • surefire-junit5
  20. 20. 20 Launcher API • Used by IDEs and build tools to launch the framework • Central API for discovering and executing tests via one or more engines • TestDiscoveryRequest – selectors and filters • Feedback provided via the TestExecutionListener API
  21. 21. 21 TestEngine API • Test engine discovers and executes tests – for a particular programming model • Automatic discovery via Java’s ServiceLoader mechanism • JUnit5TestEngine • JUnit4TestEngine • Implement your own…
  22. 22. 22 JUnit 5 Extension Model org.junit.gen5.api.extensions  @ExtendWith(...) • BeforeAllCallback • BeforeEachCallback • BeforeTestExecutionCallback • AfterTestExecutionCallback • AfterEachCallback • AfterAllCallback • ContainerExecutionCondition • TestExecutionCondition • TestInstancePostProcessor • ParameterResolver • TestExecutionExceptionHandler
  23. 23. 23 JUnit 5 Programming Model org.junit.gen5.api • Annotations and meta-annotations • Assertions and Assumptions • Custom display names • Visibility • Tagging • Conditional test execution • Dependency injection for constructors and methods • Lambda expressions and method references • Interface default methods • Nested test classes
  24. 24. 24 Annotations • @Test • @BeforeAll / @AfterAll • @BeforeEach / @AfterEach • @DisplayName • @Tag / @Tags • @Disabled • @Nested
  25. 25. 25 Assertions org.junit.gen5.api.Assertions • Limited set of core assertions – assertEquals(), assertNotNull(), etc. – plus assertThrows() and expectThrows() – and assertAll() • Supplier<String>  for lazy failure message evaluation – message is now the last parameter • For more power, use AssertJ, Hamcrest, etc.
  26. 26. 26 Assumptions org.junit.gen5.api.Assumptions • Limited set of core assumptions – For aborting tests mid-flight • assumeTrue() / assumeFalse() – BooleanSupplier, Supplier<String> • assumingThat( ? , () -> {} );
  27. 27. 27 DEMO
  28. 28. 28 Test Names • Names default to test class or test method names – characters limited based on Java syntax • Custom display names  @DisplayName – Can contain spaces, special chars, and even emoji 😱
  29. 29. 29 Dependency Injection • Extension Model meets Programming Model • ParameterResolver extension – resolves parameters for constructors or methods • TestInfo: inject into constructor, @Test, @BeforeEach, etc. – access display name, tags, class, method • TestInfoParameterResolver – eating our own dog food ;-) • See also: – TestReporter – MockitoExtension – SpringExtension
  30. 30. 30 DEMO
  31. 31. 31 Tagging • Declare @Tag or @Tags on an interface, class, or method @Tag("fast") @Test void myFastTest() { }
  32. 32. 32 Custom Tags • Declare @Tag or @Tags as a meta-annotation @Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) @Tag("fast") @Test public @interface FastTest { } @FastTest void myFastTest() { }
  33. 33. 33 Conditional Test Execution • Extension Model meets Programming Model • ContainerExecutionCondition • TestExecutionCondition • @Disabled • DisabledCondition – eating our own dog food ;-) • Deactivate via Launcher/System property – junit.conditions.deactivate = org.junit.*
  34. 34. 34 DEMO
  35. 35. 35 Interface Default Methods • Introduces the concept of a test interface – Enables multiple inheritance in tests – Kinda like testing traits • @BeforeEach / @AfterEach • @Test • @Tag • @ExtendWith • See StringTests example in user guide
  36. 36. 36 Nested Test Classes • Enables logical, hierarchical grouping of test classes – with shared initialization and state from outer classes • Declare @Nested on non-static nested classes – i.e., inner classes • You can even combine nested classes and test interfaces • See TestingAStack example in user guide
  37. 37. 37 Spring Support for JUnit 5 • SpringExtension – @ExtendWith(SpringExtension.class) – https://github.com/sbrannen/spring-test-junit5 • Works with Spring Framework 4.3 • Already supports: – Core Spring TestContext Framework features – Constructor and method injection via @Autowired, @Qualifier, @Value • Fully integrated in Spring Framework 5.0
  38. 38. 38 DEMO
  39. 39. 39 In Closing…
  40. 40. 40 What’s Missing? • Official IDE and build integration • Dynamic tests (M1) – registered as lambdas, streams, collections, etc. • Parameterized tests (M2) • Scenario tests (M3) • Parallel execution (?) • …
  41. 41. 41 Resources and Feedback Channels • Project Homepage – http://junit.org/junit5 • User Guide – http://junit.org/junit5/docs/current/user-guide • Javadoc – https://junit.ci.cloudbees.com/job/JUnit5/javadoc • GitHub – https://github.com/junit-team/junit5 • Sample Projects – https://github.com/junit-team/junit5-samples • Twitter – https://twitter.com/JUnitTeam • Stack Overflow – http://stackoverflow.com/tags/junit5
  42. 42. 42 Q & A Sam Brannen @sam_brannen www.slideshare.net/sbrannen www.swiftmind.com

×