SlideShare a Scribd company logo
Sam Brannen
@sam_brannen
SpringOne 2021
Testing with
and
Copyright © 2021 VMware, Inc. or its affiliates.
JUnit
©2020 VMware, Inc. 2
This presentation may contain product features or functionality that are currently under
development.
This overview of new technology represents no commitment from VMware to deliver these
features in any generally available product.
Features are subject to change, and must not be included in contracts, purchase orders, or sales
agreements of any kind.
Technical feasibility and market demand will affect final delivery.
Pricing and packaging for any new features/functionality/technology discussed or presented, have
not been determined.
The information in this presentation is for informational purposes only and may not be incorporated into any contract. There is no
commitment or obligation to deliver any items presented herein.
Disclaimer
Sam Brannen
● Staff Software Engineer
● Java Developer for over 20 years
● Spring Framework Core Committer since 2007
● JUnit 5 Core Committer since October 2015
Cover w/ Image
Agenda
● JUnit 5.7
● JUnit 5.8
● Spring 5.3
● GraalVM
● Q&A
JUnit Jupiter Support in Spring
JUnit Jupiter and Spring are a great match for testing
● Spring Framework
● @ExtendWith(SpringExtension.class)
● @SpringJUnitConfig
● @SpringJUnitWebConfig
● Spring Boot
● @SpringBootTest
● @WebMvcTest, etc.
JUnit 5.7
Odds and Ends
https://junit.org/junit5/docs/5.7.2/release-notes/
● Numerous APIs promoted from experimental to stable
● Improvements to EngineTestKit
● Improvements to Assertions
● Improvements to @CsvFileSource and @CsvSource
● Custom disabledReason for all @Enabled* / @Disabled* annotations
Major Features in 5.7
● Java Flight Recorder support
● junit.jupiter.testmethod.order.default configuration parameter to set the
default MethodOrderer
● used unless @TestMethodOrder is present
● @EnabledIf and @DisabledIf: based on condition methods
● @Isolated: run the test class in isolation during parallel execution
● TypedArgumentConverter for converting one specific type to another
○ use with @ConvertWith in a @ParameterizedTest
○ enhancements and bug fixes in 5.8
JUnit 5.8
Major Features in JUnit Platform 1.8
● Declarative test suites via @Suite classes
● SuiteTestEngine in junit-platform-suite-engine module
● new annotations in junit-platform-suite-api module
■ @Suite, @ConfigurationParameter, @SelectUris, @SelectFile, etc.
● UniqueIdTrackingListener
○ TestExecutionListener that tracks the unique IDs of all tests
○ generates a file containing the unique IDs
○ can be used to rerun those tests 
■ for example, with GraalVM Native Build Tools
Example: Suites before 5.8 – Soon to be Deprecated
// Uses JUnit 4 to run JUnit 5
@RunWith(JUnitPlatform.class)
@SuiteDisplayName("Integration Tests")
@IncludeEngines("junit-jupiter")
@SelectPackages("com.example")
@IncludeTags("integration-test")
public class IntegrationTestSuite {
}
Example: Suites with JUnit 5.8
// Uses JUnit 5 to run JUnit 5
@Suite
@SuiteDisplayName("Integration Tests")
@IncludeEngines("junit-jupiter")
@SelectPackages("com.example")
@IncludeTags("integration-test")
public class IntegrationTestSuite {
}
Small Enhancements in JUnit 5.8
https://junit.org/junit5/docs/snapshot/release-notes/
● More fine-grained Java Flight Recorder (JFR) events
● plus support on Java 8 update 262 or higher
● assertThrowsExactly()
○ alternative to assertThrows()
● assertInstanceOf()
○ instead of assertTrue(obj instanceof X)
● @RegisterExtension fields may now be private
New in JUnit Jupiter 5.8
Test Class Execution Order
● ClassOrderer API analogous to the MethodOrderer API
○ ClassName
○ DisplayName
○ OrderAnnotation
○ Random
● Global configuration via junit.jupiter.testclass.order.default configuration
parameter for all test classes
● for example, to optimize the build
● Local configuration via @TestClassOrder for @Nested test classes
Example: @TestClassOrder
@TestClassOrder(ClassOrderer.OrderAnnotation.class)
class OrderedNestedTests {
@Nested
@Order(1)
class PrimaryTests {
@Test
void test1() {}
}
@Nested
@Order(2)
class SecondaryTests {
@Test
void test2() {}
}
}
@TempDir – New Behavior
Due to popular demand from the community…
● @TempDir previously created a single temporary directory per context
● @TempDir can now be used to create multiple temporary directories
● JUnit now creates a separate temporary directory per @TempDir annotation
● Revert to the old behavior by setting the junit.jupiter.tempdir.scope
configuration parameter to per_context
@ExtendWith on Fields and Parameters
Improves programming model
● @RegisterExtension: register extensions via fields programmatically
○ nothing new
● @ExtendWith: can now register extensions via fields and parameters declaratively
● fields: static or instance
● parameters: constructor, lifecycle method, test method
● typically as a meta-annotation
● avoids the need to declare @ExtendWith at the class or method level
Example: RandomNumberExtension
@Target({ ElementType.FIELD, ElementType.PARAMETER })
@Retention(RetentionPolicy.RUNTIME)
@ExtendWith(RandomNumberExtension.class)
public @interface Random {
}
class RandomNumberExtension implements BeforeAllCallback,
BeforeEachCallback, ParameterResolver {
// implementation...
}
Example: @Random in Action
class RandomNumberTests {
@Random
private int randomNumber1;
RandomNumberTests(@Random int randomNumber2) {
}
@BeforeEach
void beforeEach(@Random int randomNumber3) {
}
@Test
void test(@Random int randomNumber4) {
}
}
Named API
● Named: container that associates a name with a given payload
○ The meaning of the payload depends on the context
○ Named.of() vs. Named.named()
● DynamicTests.stream() can consume Named input and will use each name-value pair
as the display name and value for each generated dynamic test
● In parameterized tests using @MethodSource or @ArgumentSource, arguments can
now have explicit names supplied via the Named API
○ explicit name used in display name instead of the argument value
Example: Named Dynamic Tests
@TestFactory
Stream<DynamicTest> dynamicTests() {
Stream<Named<String>> inputStream = Stream.of(
named("racecar is a palindrome", "racecar"),
named("radar is also a palindrome", "radar"),
named("mom also seems to be a palindrome", "mom"),
named("dad is yet another palindrome", "dad")
);
return DynamicTest.stream(inputStream,
text -> assertTrue(isPalindrome(text)));
}
AutoCloseable Arguments in Parameterized Tests
● In parameterized tests, arguments that implement AutoCloseable will now be
automatically closed after the test completes
● Allows for automatic cleanup of resources
○ closing a file
○ stopping a server
○ etc.
● Similar to the CloseableResource support in the ExtensionContext.Store
Spring Framework 5.3
New in Spring Framework 5.3 GA to 5.3.9
https://github.com/spring-projects/spring-framework/releases
● Test configuration is now discovered on enclosing classes for @Nested test classes
● ApplicationEvents abstraction for capturing application events published in the
ApplicationContext during a test
● Set spring.test.constructor.autowire.mode in junit-platform.properties
● Detection for @Autowired violations in JUnit Jupiter
● Improvements for file uploads and multipart support in MockMvc and
MockRestServiceServer
● Various enhancements in MockHttpServletRequest and MockHttpServletResponse
● Improved SQL script parsing regarding delimiters and comments
Example: @Nested tests before 5.3
@SpringJUnitConfig(TestConfig.class)
@ActiveProfiles("dev")
@Transactional
class DevTests {
@Nested
@SpringJUnitConfig(TestConfig.class)
@ActiveProfiles("dev")
@Transactional
class OrderTests { /* tests */ }
@Nested
@SpringJUnitConfig(PricingConfig.class)
class PricingTests { /* tests */ }
}
Example: @Nested tests after 5.3
@SpringJUnitConfig(TestConfig.class)
@ActiveProfiles("dev")
@Transactional
class DevTests {
@Nested
class OrderTests { /* tests */ }
@Nested
@NestedTestConfiguration(OVERRIDE)
@SpringJUnitConfig(PricingConfig.class)
class PricingTests { /* tests */ }
}
Example: ApplicationEvents
@SpringJUnitConfig(/* ... */)
@RecordApplicationEvents
class OrderServiceTests {
@Autowired OrderService orderService;
@Autowired ApplicationEvents events;
@Test
void submitOrder() {
// Invoke method in OrderService that publishes an event
orderService.submitOrder(new Order(/* ... */));
// Verify that 1 OrderSubmitted event was published
assertThat(events.stream(OrderSubmitted.class)).hasSize(1);
}
}
Coming in Spring Framework 5.3.10
Improving every step of the way…
● ExceptionCollector testing utility
● Soft assertions for MockMvc and WebTestClient
● Support for HtmlFileInput.setData() with HtmlUnit and MockMvc
● setDefaultCharacterEncoding() in MockHttpServletResponse
● Default character encoding for responses in MockMvc
Example: MockMvc without Soft Assertions
mockMvc.perform(get("/person/5").accept(APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(jsonPath("$.name").value("Jane"));
Example: MockMvc with Soft Assertions
mockMvc.perform(get("/person/5").accept(APPLICATION_JSON))
.andExpectAll(
status().isOk(),
jsonPath("$.name").value("Jane")
);
Example: WebTestClient without Soft Assertions
webTestClient.get().uri("/test").exchange()
.expectStatus().isOk()
.expectBody(String.class).isEqualTo("hello");
Example: WebTestClient with Soft Assertions
webTestClient.get().uri("/test").exchange()
.expectAll(
spec -> spec.expectStatus().isOk(),
spec -> spec.expectBody(String.class).isEqualTo("hello")
);
Example: MockMvc default response character encoding
MockMvc mockMvc;
@BeforeEach
void setup(WebApplicationContext wac) {
this.mockMvc = webAppContextSetup(wac)
.defaultResponseCharacterEncoding(StandardCharsets.UTF_8)
.build();
}
@Test
void getPerson() throws Exception {
this.mockMvc.perform(get("/person/1").characterEncoding(UTF_8))
.andExpect(status().isOk())
.andExpect(content().encoding(UTF_8));
}
GraalVM Native Build Tools
GraalVM Native Build Tools
“The Native Build Tools project provides plugins for different build
tools to add support for building and testing native applications
written in Java (or any other language compiled to JVM bytecode)”
● Collaboration between the GraalVM team, the Spring team, and recently the
Micronaut team as well
● Build tools
● Gradle plugin
● Maven plugin
● Compiling native images
● Testing within a native image using the JUnit Platform
Why test within a native image?
● Java is “write once; run anywhere”.
● … but a native image is not your app running on the JVM.
● You could just rely on your normal JVM-based test suite.
● … because your app is already tested – right?
● You could test your native app from the outside – for example, via HTTP endpoints.
○ … but do you have HTTP endpoints for every feature of your app?
● Best practice:
○ Write your JVM tests like you normally do.
○ Run the same tests (or a subset) within a native image.
How can a Native Build Tools plugin help?
● Runs your tests in the JVM first, using the UniqueIdTrackingListener
○ Tracks the tests you want to run in the native image
○ Necessary since classpath scanning doesn’t work in a native image
● If your tests or the code you’re testing requires reflection, you might need to run your
JVM tests with the GraalVM agent
● Compiles your app and tests into a native image using the JUnitPlatformFeature
(GraalVM Feature)
● Runs your tests within the native image using the NativeImageJUnitLauncher
○ Launches the JUnit Platform and selects your tests based on the output of the
UniqueIdTrackingListener
● Outputs results to the console and XML test reports
How to use Native Build Tools
● Follow the instructions for configuring your Gradle or Maven build
○ https://graalvm.github.io/native-build-tools/
● Or use the Spring Native support configured for your automatically
○ https://start.spring.io
● Gradle:
○ gradle nativeTest
○ gradle –Pagent test and gradle –Pagent nativeTest
● Maven:
○ mvn –Dskip -Pnative test
Things to keep in mind
● Not everything works in a native image
○ Classpath scanning
○ Dynamic class creation
○ Mockito and various mocking libraries
● You might need to exclude certain tests within a native image
○ For example, via tags or a custom ExecutionCondition in JUnit Jupiter
● Building a native image can take a long time
○ Probably not something you want to do multiple times a day
○ A dedicated CI pipeline might be a better choice
Q&A
Thank you
Twitter: @sam_brannen
Slack: #session-testing-with-junit-5-spring-and-native-images
© 2021 Spring. A VMware-backed project.
and JUnit

More Related Content

What's hot (20)

PPTX
Spring Boot
Jiayun Zhou
 
PDF
Spring Boot
Pei-Tang Huang
 
PPT
Monitoring using Prometheus and Grafana
Arvind Kumar G.S
 
PPTX
Spring Boot Tutorial
Naphachara Rattanawilai
 
PDF
Spring boot jpa
Hamid Ghorbani
 
PDF
Spring Framework - Data Access
Dzmitry Naskou
 
PDF
Real Life Clean Architecture
Mattia Battiston
 
PPT
Spring ppt
Mumbai Academisc
 
PDF
Java Tutorial | Java Programming Tutorial | Java Basics | Java Training | Edu...
Edureka!
 
PDF
Testing with JUnit 5 and Spring - Spring I/O 2022
Sam Brannen
 
PDF
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Edureka!
 
PDF
Pentesting GraphQL Applications
Neelu Tripathy
 
PDF
GraalVM: Run Programs Faster Everywhere
J On The Beach
 
PPTX
Karate for Complex Web-Service API Testing by Peter Thomas
intuit_india
 
PDF
Spring Framework - AOP
Dzmitry Naskou
 
PDF
Spring integration을 통해_살펴본_메시징_세계
Wangeun Lee
 
PDF
Spring Data JPA
Knoldus Inc.
 
PPTX
Java Spring Framework
Mehul Jariwala
 
PPTX
Node js Introduction
sanskriti agarwal
 
PDF
Clean Lambdas & Streams in Java8
Victor Rentea
 
Spring Boot
Jiayun Zhou
 
Spring Boot
Pei-Tang Huang
 
Monitoring using Prometheus and Grafana
Arvind Kumar G.S
 
Spring Boot Tutorial
Naphachara Rattanawilai
 
Spring boot jpa
Hamid Ghorbani
 
Spring Framework - Data Access
Dzmitry Naskou
 
Real Life Clean Architecture
Mattia Battiston
 
Spring ppt
Mumbai Academisc
 
Java Tutorial | Java Programming Tutorial | Java Basics | Java Training | Edu...
Edureka!
 
Testing with JUnit 5 and Spring - Spring I/O 2022
Sam Brannen
 
Node.js Tutorial for Beginners | Node.js Web Application Tutorial | Node.js T...
Edureka!
 
Pentesting GraphQL Applications
Neelu Tripathy
 
GraalVM: Run Programs Faster Everywhere
J On The Beach
 
Karate for Complex Web-Service API Testing by Peter Thomas
intuit_india
 
Spring Framework - AOP
Dzmitry Naskou
 
Spring integration을 통해_살펴본_메시징_세계
Wangeun Lee
 
Spring Data JPA
Knoldus Inc.
 
Java Spring Framework
Mehul Jariwala
 
Node js Introduction
sanskriti agarwal
 
Clean Lambdas & Streams in Java8
Victor Rentea
 

Similar to Testing with JUnit 5 and Spring (20)

PDF
JUnit 5 - Evolution and Innovation - SpringOne Platform 2019
Sam Brannen
 
PDF
JUnit 5 — New Opportunities for Testing on the JVM
VMware Tanzu
 
PPTX
Testing with Spring, AOT, GraalVM, and JUnit 5 - Spring I/O 2023
Sam Brannen
 
PDF
JUnit 5 - New Opportunities for Testing on the JVM
Sam Brannen
 
PPTX
JUnit 5: What's New and What's Coming - Spring I/O 2019
Sam Brannen
 
PPTX
JUnit 5 - from Lambda to Alpha and beyond
Sam Brannen
 
PDF
What is new in JUnit5
Richard Langlois P. Eng.
 
PPTX
Testing Spring Applications
Muhammad Abdullah
 
PDF
JUnit 5
Scott Leberknight
 
PPTX
Testing Spring Boot application in post-JUnit 4 world
Yura Nosenko
 
PDF
An Introduction to JUnit 5 and how to use it with Spring boot tests and Mockito
shaunthomas999
 
PPTX
Junit5 brujug
Tim Schmitte
 
PPTX
Testing with Junit4
Amila Paranawithana
 
PDF
Testing with Spring: An Introduction
Sam Brannen
 
PPTX
Introduction to JUnit testing in OpenDaylight
OpenDaylight
 
PDF
Spring Framework 5.2: Core Container Revisited
VMware Tanzu
 
PPTX
Software Testing and JUnit and Best Practices
ssuserbad56d
 
PPTX
Renaissance of JUnit - Introduction to JUnit 5
Jimmy Lu
 
PDF
Testing with Spring 4.x
Sam Brannen
 
JUnit 5 - Evolution and Innovation - SpringOne Platform 2019
Sam Brannen
 
JUnit 5 — New Opportunities for Testing on the JVM
VMware Tanzu
 
Testing with Spring, AOT, GraalVM, and JUnit 5 - Spring I/O 2023
Sam Brannen
 
JUnit 5 - New Opportunities for Testing on the JVM
Sam Brannen
 
JUnit 5: What's New and What's Coming - Spring I/O 2019
Sam Brannen
 
JUnit 5 - from Lambda to Alpha and beyond
Sam Brannen
 
What is new in JUnit5
Richard Langlois P. Eng.
 
Testing Spring Applications
Muhammad Abdullah
 
Testing Spring Boot application in post-JUnit 4 world
Yura Nosenko
 
An Introduction to JUnit 5 and how to use it with Spring boot tests and Mockito
shaunthomas999
 
Junit5 brujug
Tim Schmitte
 
Testing with Junit4
Amila Paranawithana
 
Testing with Spring: An Introduction
Sam Brannen
 
Introduction to JUnit testing in OpenDaylight
OpenDaylight
 
Spring Framework 5.2: Core Container Revisited
VMware Tanzu
 
Software Testing and JUnit and Best Practices
ssuserbad56d
 
Renaissance of JUnit - Introduction to JUnit 5
Jimmy Lu
 
Testing with Spring 4.x
Sam Brannen
 
Ad

More from VMware Tanzu (20)

PDF
Spring into AI presented by Dan Vega 5/14
VMware Tanzu
 
PDF
What AI Means For Your Product Strategy And What To Do About It
VMware Tanzu
 
PDF
Make the Right Thing the Obvious Thing at Cardinal Health 2023
VMware Tanzu
 
PPTX
Enhancing DevEx and Simplifying Operations at Scale
VMware Tanzu
 
PDF
Spring Update | July 2023
VMware Tanzu
 
PPTX
Platforms, Platform Engineering, & Platform as a Product
VMware Tanzu
 
PPTX
Building Cloud Ready Apps
VMware Tanzu
 
PDF
Spring Boot 3 And Beyond
VMware Tanzu
 
PDF
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
VMware Tanzu
 
PDF
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
VMware Tanzu
 
PDF
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
VMware Tanzu
 
PPTX
tanzu_developer_connect.pptx
VMware Tanzu
 
PDF
Tanzu Virtual Developer Connect Workshop - French
VMware Tanzu
 
PDF
Tanzu Developer Connect Workshop - English
VMware Tanzu
 
PDF
Virtual Developer Connect Workshop - English
VMware Tanzu
 
PDF
Tanzu Developer Connect - French
VMware Tanzu
 
PDF
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
VMware Tanzu
 
PDF
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
VMware Tanzu
 
PDF
SpringOne Tour: The Influential Software Engineer
VMware Tanzu
 
PDF
SpringOne Tour: Domain-Driven Design: Theory vs Practice
VMware Tanzu
 
Spring into AI presented by Dan Vega 5/14
VMware Tanzu
 
What AI Means For Your Product Strategy And What To Do About It
VMware Tanzu
 
Make the Right Thing the Obvious Thing at Cardinal Health 2023
VMware Tanzu
 
Enhancing DevEx and Simplifying Operations at Scale
VMware Tanzu
 
Spring Update | July 2023
VMware Tanzu
 
Platforms, Platform Engineering, & Platform as a Product
VMware Tanzu
 
Building Cloud Ready Apps
VMware Tanzu
 
Spring Boot 3 And Beyond
VMware Tanzu
 
Spring Cloud Gateway - SpringOne Tour 2023 Charles Schwab.pdf
VMware Tanzu
 
Simplify and Scale Enterprise Apps in the Cloud | Boston 2023
VMware Tanzu
 
Simplify and Scale Enterprise Apps in the Cloud | Seattle 2023
VMware Tanzu
 
tanzu_developer_connect.pptx
VMware Tanzu
 
Tanzu Virtual Developer Connect Workshop - French
VMware Tanzu
 
Tanzu Developer Connect Workshop - English
VMware Tanzu
 
Virtual Developer Connect Workshop - English
VMware Tanzu
 
Tanzu Developer Connect - French
VMware Tanzu
 
Simplify and Scale Enterprise Apps in the Cloud | Dallas 2023
VMware Tanzu
 
SpringOne Tour: Deliver 15-Factor Applications on Kubernetes with Spring Boot
VMware Tanzu
 
SpringOne Tour: The Influential Software Engineer
VMware Tanzu
 
SpringOne Tour: Domain-Driven Design: Theory vs Practice
VMware Tanzu
 
Ad

Recently uploaded (20)

PDF
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
PPTX
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
PDF
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
PDF
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
PDF
Simplify React app login with asgardeo-sdk
vaibhav289687
 
PDF
AI + DevOps = Smart Automation with devseccops.ai.pdf
Devseccops.ai
 
PDF
How to Hire AI Developers_ Step-by-Step Guide in 2025.pdf
DianApps Technologies
 
PPTX
AEM User Group: India Chapter Kickoff Meeting
jennaf3
 
PPTX
Change Common Properties in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PDF
IObit Driver Booster Pro 12.4.0.585 Crack Free Download
henryc1122g
 
PDF
Wondershare PDFelement Pro Crack for MacOS New Version Latest 2025
bashirkhan333g
 
PDF
Dipole Tech Innovations – Global IT Solutions for Business Growth
dipoletechi3
 
PDF
Empower Your Tech Vision- Why Businesses Prefer to Hire Remote Developers fro...
logixshapers59
 
PPTX
Get Started with Maestro: Agent, Robot, and Human in Action – Session 5 of 5
klpathrudu
 
PPTX
Agentic Automation Journey Series Day 2 – Prompt Engineering for UiPath Agents
klpathrudu
 
PPTX
Smart Doctor Appointment Booking option in odoo.pptx
AxisTechnolabs
 
PPTX
Finding Your License Details in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
PPTX
iaas vs paas vs saas :choosing your cloud strategy
CloudlayaTechnology
 
PDF
ERP Consulting Services and Solutions by Contetra Pvt Ltd
jayjani123
 
PDF
AOMEI Partition Assistant Crack 10.8.2 + WinPE Free Downlaod New Version 2025
bashirkhan333g
 
MiniTool Partition Wizard Free Crack + Full Free Download 2025
bashirkhan333g
 
Home Care Tools: Benefits, features and more
Third Rock Techkno
 
Open Chain Q2 Steering Committee Meeting - 2025-06-25
Shane Coughlan
 
Download Canva Pro 2025 PC Crack Full Latest Version
bashirkhan333g
 
Simplify React app login with asgardeo-sdk
vaibhav289687
 
AI + DevOps = Smart Automation with devseccops.ai.pdf
Devseccops.ai
 
How to Hire AI Developers_ Step-by-Step Guide in 2025.pdf
DianApps Technologies
 
AEM User Group: India Chapter Kickoff Meeting
jennaf3
 
Change Common Properties in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
IObit Driver Booster Pro 12.4.0.585 Crack Free Download
henryc1122g
 
Wondershare PDFelement Pro Crack for MacOS New Version Latest 2025
bashirkhan333g
 
Dipole Tech Innovations – Global IT Solutions for Business Growth
dipoletechi3
 
Empower Your Tech Vision- Why Businesses Prefer to Hire Remote Developers fro...
logixshapers59
 
Get Started with Maestro: Agent, Robot, and Human in Action – Session 5 of 5
klpathrudu
 
Agentic Automation Journey Series Day 2 – Prompt Engineering for UiPath Agents
klpathrudu
 
Smart Doctor Appointment Booking option in odoo.pptx
AxisTechnolabs
 
Finding Your License Details in IBM SPSS Statistics Version 31.pptx
Version 1 Analytics
 
iaas vs paas vs saas :choosing your cloud strategy
CloudlayaTechnology
 
ERP Consulting Services and Solutions by Contetra Pvt Ltd
jayjani123
 
AOMEI Partition Assistant Crack 10.8.2 + WinPE Free Downlaod New Version 2025
bashirkhan333g
 

Testing with JUnit 5 and Spring

  • 1. Sam Brannen @sam_brannen SpringOne 2021 Testing with and Copyright © 2021 VMware, Inc. or its affiliates. JUnit
  • 2. ©2020 VMware, Inc. 2 This presentation may contain product features or functionality that are currently under development. This overview of new technology represents no commitment from VMware to deliver these features in any generally available product. Features are subject to change, and must not be included in contracts, purchase orders, or sales agreements of any kind. Technical feasibility and market demand will affect final delivery. Pricing and packaging for any new features/functionality/technology discussed or presented, have not been determined. The information in this presentation is for informational purposes only and may not be incorporated into any contract. There is no commitment or obligation to deliver any items presented herein. Disclaimer
  • 3. Sam Brannen ● Staff Software Engineer ● Java Developer for over 20 years ● Spring Framework Core Committer since 2007 ● JUnit 5 Core Committer since October 2015
  • 4. Cover w/ Image Agenda ● JUnit 5.7 ● JUnit 5.8 ● Spring 5.3 ● GraalVM ● Q&A
  • 5. JUnit Jupiter Support in Spring JUnit Jupiter and Spring are a great match for testing ● Spring Framework ● @ExtendWith(SpringExtension.class) ● @SpringJUnitConfig ● @SpringJUnitWebConfig ● Spring Boot ● @SpringBootTest ● @WebMvcTest, etc.
  • 7. Odds and Ends https://junit.org/junit5/docs/5.7.2/release-notes/ ● Numerous APIs promoted from experimental to stable ● Improvements to EngineTestKit ● Improvements to Assertions ● Improvements to @CsvFileSource and @CsvSource ● Custom disabledReason for all @Enabled* / @Disabled* annotations
  • 8. Major Features in 5.7 ● Java Flight Recorder support ● junit.jupiter.testmethod.order.default configuration parameter to set the default MethodOrderer ● used unless @TestMethodOrder is present ● @EnabledIf and @DisabledIf: based on condition methods ● @Isolated: run the test class in isolation during parallel execution ● TypedArgumentConverter for converting one specific type to another ○ use with @ConvertWith in a @ParameterizedTest ○ enhancements and bug fixes in 5.8
  • 10. Major Features in JUnit Platform 1.8 ● Declarative test suites via @Suite classes ● SuiteTestEngine in junit-platform-suite-engine module ● new annotations in junit-platform-suite-api module ■ @Suite, @ConfigurationParameter, @SelectUris, @SelectFile, etc. ● UniqueIdTrackingListener ○ TestExecutionListener that tracks the unique IDs of all tests ○ generates a file containing the unique IDs ○ can be used to rerun those tests  ■ for example, with GraalVM Native Build Tools
  • 11. Example: Suites before 5.8 – Soon to be Deprecated // Uses JUnit 4 to run JUnit 5 @RunWith(JUnitPlatform.class) @SuiteDisplayName("Integration Tests") @IncludeEngines("junit-jupiter") @SelectPackages("com.example") @IncludeTags("integration-test") public class IntegrationTestSuite { }
  • 12. Example: Suites with JUnit 5.8 // Uses JUnit 5 to run JUnit 5 @Suite @SuiteDisplayName("Integration Tests") @IncludeEngines("junit-jupiter") @SelectPackages("com.example") @IncludeTags("integration-test") public class IntegrationTestSuite { }
  • 13. Small Enhancements in JUnit 5.8 https://junit.org/junit5/docs/snapshot/release-notes/ ● More fine-grained Java Flight Recorder (JFR) events ● plus support on Java 8 update 262 or higher ● assertThrowsExactly() ○ alternative to assertThrows() ● assertInstanceOf() ○ instead of assertTrue(obj instanceof X) ● @RegisterExtension fields may now be private
  • 14. New in JUnit Jupiter 5.8
  • 15. Test Class Execution Order ● ClassOrderer API analogous to the MethodOrderer API ○ ClassName ○ DisplayName ○ OrderAnnotation ○ Random ● Global configuration via junit.jupiter.testclass.order.default configuration parameter for all test classes ● for example, to optimize the build ● Local configuration via @TestClassOrder for @Nested test classes
  • 16. Example: @TestClassOrder @TestClassOrder(ClassOrderer.OrderAnnotation.class) class OrderedNestedTests { @Nested @Order(1) class PrimaryTests { @Test void test1() {} } @Nested @Order(2) class SecondaryTests { @Test void test2() {} } }
  • 17. @TempDir – New Behavior Due to popular demand from the community… ● @TempDir previously created a single temporary directory per context ● @TempDir can now be used to create multiple temporary directories ● JUnit now creates a separate temporary directory per @TempDir annotation ● Revert to the old behavior by setting the junit.jupiter.tempdir.scope configuration parameter to per_context
  • 18. @ExtendWith on Fields and Parameters Improves programming model ● @RegisterExtension: register extensions via fields programmatically ○ nothing new ● @ExtendWith: can now register extensions via fields and parameters declaratively ● fields: static or instance ● parameters: constructor, lifecycle method, test method ● typically as a meta-annotation ● avoids the need to declare @ExtendWith at the class or method level
  • 19. Example: RandomNumberExtension @Target({ ElementType.FIELD, ElementType.PARAMETER }) @Retention(RetentionPolicy.RUNTIME) @ExtendWith(RandomNumberExtension.class) public @interface Random { } class RandomNumberExtension implements BeforeAllCallback, BeforeEachCallback, ParameterResolver { // implementation... }
  • 20. Example: @Random in Action class RandomNumberTests { @Random private int randomNumber1; RandomNumberTests(@Random int randomNumber2) { } @BeforeEach void beforeEach(@Random int randomNumber3) { } @Test void test(@Random int randomNumber4) { } }
  • 21. Named API ● Named: container that associates a name with a given payload ○ The meaning of the payload depends on the context ○ Named.of() vs. Named.named() ● DynamicTests.stream() can consume Named input and will use each name-value pair as the display name and value for each generated dynamic test ● In parameterized tests using @MethodSource or @ArgumentSource, arguments can now have explicit names supplied via the Named API ○ explicit name used in display name instead of the argument value
  • 22. Example: Named Dynamic Tests @TestFactory Stream<DynamicTest> dynamicTests() { Stream<Named<String>> inputStream = Stream.of( named("racecar is a palindrome", "racecar"), named("radar is also a palindrome", "radar"), named("mom also seems to be a palindrome", "mom"), named("dad is yet another palindrome", "dad") ); return DynamicTest.stream(inputStream, text -> assertTrue(isPalindrome(text))); }
  • 23. AutoCloseable Arguments in Parameterized Tests ● In parameterized tests, arguments that implement AutoCloseable will now be automatically closed after the test completes ● Allows for automatic cleanup of resources ○ closing a file ○ stopping a server ○ etc. ● Similar to the CloseableResource support in the ExtensionContext.Store
  • 25. New in Spring Framework 5.3 GA to 5.3.9 https://github.com/spring-projects/spring-framework/releases ● Test configuration is now discovered on enclosing classes for @Nested test classes ● ApplicationEvents abstraction for capturing application events published in the ApplicationContext during a test ● Set spring.test.constructor.autowire.mode in junit-platform.properties ● Detection for @Autowired violations in JUnit Jupiter ● Improvements for file uploads and multipart support in MockMvc and MockRestServiceServer ● Various enhancements in MockHttpServletRequest and MockHttpServletResponse ● Improved SQL script parsing regarding delimiters and comments
  • 26. Example: @Nested tests before 5.3 @SpringJUnitConfig(TestConfig.class) @ActiveProfiles("dev") @Transactional class DevTests { @Nested @SpringJUnitConfig(TestConfig.class) @ActiveProfiles("dev") @Transactional class OrderTests { /* tests */ } @Nested @SpringJUnitConfig(PricingConfig.class) class PricingTests { /* tests */ } }
  • 27. Example: @Nested tests after 5.3 @SpringJUnitConfig(TestConfig.class) @ActiveProfiles("dev") @Transactional class DevTests { @Nested class OrderTests { /* tests */ } @Nested @NestedTestConfiguration(OVERRIDE) @SpringJUnitConfig(PricingConfig.class) class PricingTests { /* tests */ } }
  • 28. Example: ApplicationEvents @SpringJUnitConfig(/* ... */) @RecordApplicationEvents class OrderServiceTests { @Autowired OrderService orderService; @Autowired ApplicationEvents events; @Test void submitOrder() { // Invoke method in OrderService that publishes an event orderService.submitOrder(new Order(/* ... */)); // Verify that 1 OrderSubmitted event was published assertThat(events.stream(OrderSubmitted.class)).hasSize(1); } }
  • 29. Coming in Spring Framework 5.3.10 Improving every step of the way… ● ExceptionCollector testing utility ● Soft assertions for MockMvc and WebTestClient ● Support for HtmlFileInput.setData() with HtmlUnit and MockMvc ● setDefaultCharacterEncoding() in MockHttpServletResponse ● Default character encoding for responses in MockMvc
  • 30. Example: MockMvc without Soft Assertions mockMvc.perform(get("/person/5").accept(APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath("$.name").value("Jane"));
  • 31. Example: MockMvc with Soft Assertions mockMvc.perform(get("/person/5").accept(APPLICATION_JSON)) .andExpectAll( status().isOk(), jsonPath("$.name").value("Jane") );
  • 32. Example: WebTestClient without Soft Assertions webTestClient.get().uri("/test").exchange() .expectStatus().isOk() .expectBody(String.class).isEqualTo("hello");
  • 33. Example: WebTestClient with Soft Assertions webTestClient.get().uri("/test").exchange() .expectAll( spec -> spec.expectStatus().isOk(), spec -> spec.expectBody(String.class).isEqualTo("hello") );
  • 34. Example: MockMvc default response character encoding MockMvc mockMvc; @BeforeEach void setup(WebApplicationContext wac) { this.mockMvc = webAppContextSetup(wac) .defaultResponseCharacterEncoding(StandardCharsets.UTF_8) .build(); } @Test void getPerson() throws Exception { this.mockMvc.perform(get("/person/1").characterEncoding(UTF_8)) .andExpect(status().isOk()) .andExpect(content().encoding(UTF_8)); }
  • 36. GraalVM Native Build Tools “The Native Build Tools project provides plugins for different build tools to add support for building and testing native applications written in Java (or any other language compiled to JVM bytecode)” ● Collaboration between the GraalVM team, the Spring team, and recently the Micronaut team as well ● Build tools ● Gradle plugin ● Maven plugin ● Compiling native images ● Testing within a native image using the JUnit Platform
  • 37. Why test within a native image? ● Java is “write once; run anywhere”. ● … but a native image is not your app running on the JVM. ● You could just rely on your normal JVM-based test suite. ● … because your app is already tested – right? ● You could test your native app from the outside – for example, via HTTP endpoints. ○ … but do you have HTTP endpoints for every feature of your app? ● Best practice: ○ Write your JVM tests like you normally do. ○ Run the same tests (or a subset) within a native image.
  • 38. How can a Native Build Tools plugin help? ● Runs your tests in the JVM first, using the UniqueIdTrackingListener ○ Tracks the tests you want to run in the native image ○ Necessary since classpath scanning doesn’t work in a native image ● If your tests or the code you’re testing requires reflection, you might need to run your JVM tests with the GraalVM agent ● Compiles your app and tests into a native image using the JUnitPlatformFeature (GraalVM Feature) ● Runs your tests within the native image using the NativeImageJUnitLauncher ○ Launches the JUnit Platform and selects your tests based on the output of the UniqueIdTrackingListener ● Outputs results to the console and XML test reports
  • 39. How to use Native Build Tools ● Follow the instructions for configuring your Gradle or Maven build ○ https://graalvm.github.io/native-build-tools/ ● Or use the Spring Native support configured for your automatically ○ https://start.spring.io ● Gradle: ○ gradle nativeTest ○ gradle –Pagent test and gradle –Pagent nativeTest ● Maven: ○ mvn –Dskip -Pnative test
  • 40. Things to keep in mind ● Not everything works in a native image ○ Classpath scanning ○ Dynamic class creation ○ Mockito and various mocking libraries ● You might need to exclude certain tests within a native image ○ For example, via tags or a custom ExecutionCondition in JUnit Jupiter ● Building a native image can take a long time ○ Probably not something you want to do multiple times a day ○ A dedicated CI pipeline might be a better choice
  • 41. Q&A
  • 42. Thank you Twitter: @sam_brannen Slack: #session-testing-with-junit-5-spring-and-native-images © 2021 Spring. A VMware-backed project. and JUnit