SlideShare a Scribd company logo
1 of 36
Testing with Spring, AOT,
GraalVM, and JUnit 5
Sam Brannen
@sam_brannen
● 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
Agenda
● JUnit 5.9, 5.10, 5.11
● Spring 6.0 and 6.1
● Spring AOT and GraalVM
● Demo
JUnit 5.9
https://junit.org/junit5/docs/5.9.3/release-notes/
JUnit Platform 1.9.x
● XML reports in new Open Test Reporting format
● https://github.com/ota4j-team/open-test-reporting
● New IterationSelector
● for selecting a subset of a test’s or container’s iterations
● Various improvements to ConsoleLauncher
● --single-color and --color-palette
● --list-engines
● JUnit Platform Suite Engine included in stand-alone JAR
JUnit Jupiter 5.9.x (1/2)
● Configurable cleanup mode for @TempDir
● ALWAYS, ON_SUCCESS, NEVER
● New TestInstancePreConstructCallback extension API
● counterpart to existing TestInstancePreDestroyCallback
● Reusable parameter resolution for method invocations
● via ExecutableInvoker API
● accessed via ExtensionContext
● used for @MethodSource factory methods
● @MethodSource factory methods can accept arguments
● resolved by ParameterResolver extensions
● new syntax to disambiguate local factory methods
JUnit Jupiter 5.9.x (2/2)
● Configurable thread mode for @Timeout
● INFERRED, SAME_THREAD, SEPARATE_THREAD
● @EnabledOnOs and @DisabledOnOs
● support for OS architectures
● support for FreeBSD and OpenBSD
● @EnabledInNativeImage and @DisabledInNativeImage
● enable/disable tests in GraalVM native image
● AssertionFailureBuilder
● reuse Jupiter’s logic for creating failure messages
JUnit 5.10
https://junit.org/junit5/docs/5.10.0-M1/release-notes/
JUnit Platform 1.10 M1
● Promotion of various experimental APIs to stable
● Stacktrace pruning to hide internal JUnit calls
● ConsoleLauncher
● new testfeed details mode
● new discover subcommand for test discovery without execution
● Dry-run mode for test execution
● New LauncherInterceptor SPI
● New NamespacedHierarchicalStore for use in third-party test engines
Custom ClassLoader Arrangements
● New ReflectionSupport.tryToLoadClass(…) method that accepts an explicit
ClassLoader
● ReflectionSupport.findMethod(Class<?>, String, String)
● now uses ClassLoader of the supplied class to load parameter types
● used by DiscoverySelectors.selectMethod(Class<?>, String, String)
● DiscoverySelectors methods for ClassSelector, NestedClassSelector, MethodSelector,
and NestedMethodSelector that accept an explicit ClassLoader
JUnit Jupiter 5.10 M1
● Promotion of various experimental APIs to stable
● Failure threshold for @RepeatedTest
● New TempDirFactory SPI for customizing @TempDir
● Custom ClassLoader support for @EnabledIf, @DisabledIf, @MethodSource, and
@ParameterizedTest argument conversion
● Improved configurability of parallel execution
● AnnotationBasedArgumentsProvider/AnnotationBasedArgumentConverter
● base classes for implementing ArgumentsProvider and ArgumentConverter
JUnit 5.11
https://github.com/junit-team/junit5/milestone/68
Current Roadmap
● @BeforeSuite and @AfterSuite
● in JUnit Platform @Suite engine
● Extension API for customizing the ClassLoader in Jupiter
● @FieldSource for parameterized tests
● @ContainerTemplate
● analagous to @TestTemplate
● ContainerTemplateInvocationContextProvider extension API
● @ParameterizedContainer
● effectively parameterized test classes
@FieldSource
@ParameterizedTest
@FieldSource("example.Utils#fruits")
void test(String fruit) {
/* perform assertions */
}
public class Utils {
public static final String[] fruits = {"apple", "banana"};
}
@ParameterizedContainer – Field Injection
@ParameterizedContainer
@CsvSource({"apple, 1", "banana, 2"})
class FieldInjectionTestCase {
@Parameter(0)
private String fruit;
@Parameter(1)
private int score;
@Test
void test() { /* perform assertions */ }
}
@ParameterizedContainer – Constructor Injection
@ParameterizedContainer
@CsvSource({"apple, 1", "banana, 2"})
class ConstructorInjectionTestCase {
private final String fruit;
private final int score;
ConstructorInjectionTestCase(String fruit, int score) {
this.fruit = fruit;
this.score = score;
}
@Test
void test() { /* perform assertions */ }
}
@ParameterizedContainer – Java Record
@ParameterizedContainer
@CsvSource({"apple, 1", "banana, 2"})
record RecordTestCase(String fruit, int score) {
@Test
void test() {
/* perform assertions */
}
}
Spring 6.0 - 6.1
Spring 6.0.x
● Module path scanning for "classpath*:" resource prefix
● useful for patched test modules with Maven
● Servlet API 6.0 baseline in Servlet mocks and MockMvc
● with Servlet 5.0 compatibility at runtime
● Assertions against Cookie attributes in CookieResultMatchers for MockMvc
● Default TestExecutionListeners enabled in JUnit 4 and TestNG base test classes
● Revised logging in the TestContext framework (TCF)
● ApplicationContextFailureProcessor SPI for processing ApplicationContext failures in the TCF
● used by Spring Boot
● Ahead of Time and GraalVM native image support
Spring 6.1
● Support for recording async events with @RecordApplicationEvents
● record events from threads other than main test thread
● assert events from separate thread – for example with Awaitility
● limitations in JUnit Jupiter
● Support for null in MockHttpServletResponse.setCharacterEncoding()
● New MockHttpServletRequestBuilder.setRemoteAddress() method
● Avoid repeated attempts to load failing ApplicationContext in the TestContext
framework
● Potential integration with @ParameterizedContainer in JUnit Jupiter 5.11
Spring AOT
and
GraalVM
What are AOT and GraalVM?
● AOT
● ahead-of-time optimizations
● part of the build process
● utilized at runtime
● GraalVM – https://www.graalvm.org/
● polyglot programming on the JVM
● native image
● compiling JVM applications to OS-specific binaries
● closed world assumptions
● no classpath
● requires runtime hints
What is Spring AOT?
● https://docs.spring.io/spring-framework/reference/core/aot.html
● AOT optimizations meant to inspect an ApplicationContext at build time and apply
decisions and discovery logic that usually happens at runtime.
● Core infrastructure in Spring Framework
● Implemented across the portfolio
● Build tools in Spring Boot
● Spring AOT optimizations are used in GraalVM native image
AOT Support for Spring Integration Tests
● https://docs.spring.io/spring-framework/reference/testing/testcontext-
framework/aot.html
● Build-time detection of Spring integration tests
● JUnit Jupiter, JUnit 4, and implicit support for TestNG etc.
● Build-time AOT processing
○ each unique test ApplicationContext will be refreshed for AOT processing
● Runtime AOT support
○ Spring integration tests use AOT-optimized ApplicationContexts
GraalVM Native Build Tools
● https://graalvm.github.io/native-build-tools/
● Collaboration between Oracle Labs, Spring, and Micronaut
● Build native image
● Run tests in native image using the JUnit Platform
● Plugins for Gradle and Maven
○ incorporated in Spring Boot build plugins
Test-specific Runtime Hints
● A lot is already built-in!
● TestRuntimeHintsRegistrar
● register globally via META-INF/spring/aot.factories
● RuntimeHintsRegistrar
● register globally via META-INF/spring/aot.factories
● register locally on a test class via @ImportRuntimeHints
● Annotate test class with @Reflective or @RegisterReflectionForBinding
Implementing Custom AOT Testing Support
● ContextLoader: implement AotContextLoader
● AOT build-time processing
● AOT runtime execution support
● Spring Framework and Spring Boot context loaders implement AotContextLoader
● TestExecutionListener: implement AotTestExecutionListener
● to participate in AOT processing
● See SqlScriptsTestExecutionListener for an example
JUnit Support for Native Images
● @EnabledInNativeImage and @DisabledInNativeImage
○ JUnit Jupiter execution conditions
● Native Build Tools (NBT) support for JUnit Platform
● Explicit support for JUnit Jupiter and JUnit 4
● Spring Boot 3 build tools
○ Gradle and Maven
○ Integration with NBT for testing support
Running Spring Integration Tests in Native Image
● Maven
○ ./mvnw -PnativeTest test
● Gradle
○ ./gradlew nativeTest
● Definitely do this before deploying a native image to production
● But this can take a considerable amount of time
● So you won’t do this multiple times a day
● Consider running tests in AOT mode on the JVM first
Disclaimer: Testing in AOT mode on JVM
● Not yet ready for prime time
○ in terms of developer experience (DX)
○ requires manual setup
● But still possible with both Maven and Gradle
○ Today I’ll show you how with Maven
● Can be useful to:
○ run tests in AOT mode on the JVM before running within a native image
○ debug failing tests first in AOT mode on the JVM
Mini Maven / Spring AOT Tutorial
● Generate AOT test sources
○ ./mvnw clean test spring-boot:process-test-aot
● Run tests in AOT mode on JVM
○ ./mvnw -Dspring.aot.enabled=true test
● Add generated sources as “test” source folder in IDE
○ target/spring-aot/test/sources/
○ output directory can be same as for your test code
● Add CGLIB compiled classes to output classpath in IDE
● alternative: @Configuration(proxyBeanMethods = false)
Testing in AOT Mode
● Run test class with -Dspring.aot.enabled=true
● That’s it!
● You should see log output like:
● Loading ApplicationContext for AOT runtime for test class springio.service.ServiceTests
● Starting AOT-processed ServiceTests
Debugging in AOT Mode
● Find mapping from test class to AOT-optimized ApplicationContext
○ org.springframework.test.context.aot.AotTestContextInitializers__Generated
○ For example, ServiceTests__TestContext001_ApplicationContextInitializer
● Set breakpoint in ApplicationContextInitializer
● Debug test class with -Dspring.aot.enabled=true
DEMO TIME! 🤞🏼
THANK YOU!
Q&A
Sam Brannen
@sam_brannen

More Related Content

What's hot

The aggregate is dead! Long live the aggregate! - SpringIO.pdf
The aggregate is dead! Long live the aggregate! - SpringIO.pdfThe aggregate is dead! Long live the aggregate! - SpringIO.pdf
The aggregate is dead! Long live the aggregate! - SpringIO.pdf
Sara Pellegrini
 

What's hot (20)

API Testing following the Test Pyramid
API Testing following the Test PyramidAPI Testing following the Test Pyramid
API Testing following the Test Pyramid
 
Apache Maven
Apache MavenApache Maven
Apache Maven
 
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
Anatomy of a Spring Boot App with Clean Architecture - Spring I/O 2023
 
Introduction to spring boot
Introduction to spring bootIntroduction to spring boot
Introduction to spring boot
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Spring Framework - AOP
Spring Framework - AOPSpring Framework - AOP
Spring Framework - AOP
 
PUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBootPUC SE Day 2019 - SpringBoot
PUC SE Day 2019 - SpringBoot
 
Introducing Swagger
Introducing SwaggerIntroducing Swagger
Introducing Swagger
 
Finally, easy integration testing with Testcontainers
Finally, easy integration testing with TestcontainersFinally, easy integration testing with Testcontainers
Finally, easy integration testing with Testcontainers
 
The aggregate is dead! Long live the aggregate! - SpringIO.pdf
The aggregate is dead! Long live the aggregate! - SpringIO.pdfThe aggregate is dead! Long live the aggregate! - SpringIO.pdf
The aggregate is dead! Long live the aggregate! - SpringIO.pdf
 
Jenkins CI
Jenkins CIJenkins CI
Jenkins CI
 
Jenkins tutorial for beginners
Jenkins tutorial for beginnersJenkins tutorial for beginners
Jenkins tutorial for beginners
 
POST/CON 2019 Workshop: Testing, Automated Testing, and Reporting APIs with P...
POST/CON 2019 Workshop: Testing, Automated Testing, and Reporting APIs with P...POST/CON 2019 Workshop: Testing, Automated Testing, and Reporting APIs with P...
POST/CON 2019 Workshop: Testing, Automated Testing, and Reporting APIs with P...
 
Jenkins Introduction
Jenkins IntroductionJenkins Introduction
Jenkins Introduction
 
Gradle - the Enterprise Automation Tool
Gradle  - the Enterprise Automation ToolGradle  - the Enterprise Automation Tool
Gradle - the Enterprise Automation Tool
 
Spring Boot Tutorial
Spring Boot TutorialSpring Boot Tutorial
Spring Boot Tutorial
 
Spring boot - an introduction
Spring boot - an introductionSpring boot - an introduction
Spring boot - an introduction
 
Spring boot
Spring bootSpring boot
Spring boot
 
Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022
Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022
Reactive Java Microservices with Spring Boot and JHipster - Spring I/O 2022
 
Spring boot
Spring bootSpring boot
Spring boot
 

Similar to Testing with Spring, AOT, GraalVM, and JUnit 5 - Spring I/O 2023

Similar to Testing with Spring, AOT, GraalVM, and JUnit 5 - Spring I/O 2023 (20)

Testing with JUnit 5 and Spring - Spring I/O 2022
Testing with JUnit 5 and Spring - Spring I/O 2022Testing with JUnit 5 and Spring - Spring I/O 2022
Testing with JUnit 5 and Spring - Spring I/O 2022
 
Maven and j unit introduction
Maven and j unit introductionMaven and j unit introduction
Maven and j unit introduction
 
The Path Towards Spring Boot Native Applications
The Path Towards Spring Boot Native ApplicationsThe Path Towards Spring Boot Native Applications
The Path Towards Spring Boot Native Applications
 
Testing Rest with Spring by Kostiantyn Baranov (Senior Software Engineer, Gl...
Testing Rest with Spring  by Kostiantyn Baranov (Senior Software Engineer, Gl...Testing Rest with Spring  by Kostiantyn Baranov (Senior Software Engineer, Gl...
Testing Rest with Spring by Kostiantyn Baranov (Senior Software Engineer, Gl...
 
Unit testing (eng)
Unit testing (eng)Unit testing (eng)
Unit testing (eng)
 
Automation for developers
Automation for developersAutomation for developers
Automation for developers
 
GeoServer Developers Workshop
GeoServer Developers WorkshopGeoServer Developers Workshop
GeoServer Developers Workshop
 
Level Up Your Integration Testing With Testcontainers
Level Up Your Integration Testing With TestcontainersLevel Up Your Integration Testing With Testcontainers
Level Up Your Integration Testing With Testcontainers
 
Quality for developers
Quality for developersQuality for developers
Quality for developers
 
Linux Kernel Selftest Framework - Quality Control for New Releases
Linux Kernel Selftest Framework - Quality Control for New ReleasesLinux Kernel Selftest Framework - Quality Control for New Releases
Linux Kernel Selftest Framework - Quality Control for New Releases
 
AOT and Native with Spring Boot 3.0
AOT and Native with Spring Boot 3.0AOT and Native with Spring Boot 3.0
AOT and Native with Spring Boot 3.0
 
Test all the things! Automated testing with Drupal 8
Test all the things! Automated testing with Drupal 8Test all the things! Automated testing with Drupal 8
Test all the things! Automated testing with Drupal 8
 
Javascript as a target language - GWT KickOff - Part 2/2
Javascript as a target language - GWT KickOff - Part 2/2Javascript as a target language - GWT KickOff - Part 2/2
Javascript as a target language - GWT KickOff - Part 2/2
 
Vietnam qa meetup
Vietnam qa meetupVietnam qa meetup
Vietnam qa meetup
 
Testing and QA Open Mic
Testing and QA Open MicTesting and QA Open Mic
Testing and QA Open Mic
 
Java Enterprise Edition
Java Enterprise EditionJava Enterprise Edition
Java Enterprise Edition
 
3 WAYS TO TEST YOUR COLDFUSION API
3 WAYS TO TEST YOUR COLDFUSION API3 WAYS TO TEST YOUR COLDFUSION API
3 WAYS TO TEST YOUR COLDFUSION API
 
3 WAYS TO TEST YOUR COLDFUSION API -
3 WAYS TO TEST YOUR COLDFUSION API - 3 WAYS TO TEST YOUR COLDFUSION API -
3 WAYS TO TEST YOUR COLDFUSION API -
 
Cloud Native CI/CD with Spring Cloud Pipelines
Cloud Native CI/CD with Spring Cloud PipelinesCloud Native CI/CD with Spring Cloud Pipelines
Cloud Native CI/CD with Spring Cloud Pipelines
 
Cloud Native CI/CD with Spring Cloud Pipelines
Cloud Native CI/CD with Spring Cloud PipelinesCloud Native CI/CD with Spring Cloud Pipelines
Cloud Native CI/CD with Spring Cloud Pipelines
 

More from Sam Brannen

Testing Web Apps with Spring Framework 3.2
Testing Web Apps with Spring Framework 3.2Testing Web Apps with Spring Framework 3.2
Testing Web Apps with Spring Framework 3.2
Sam Brannen
 

More from Sam Brannen (20)

JUnit 5 - Evolution and Innovation - SpringOne Platform 2019
JUnit 5 - Evolution and Innovation - SpringOne Platform 2019JUnit 5 - Evolution and Innovation - SpringOne Platform 2019
JUnit 5 - Evolution and Innovation - SpringOne Platform 2019
 
JUnit 5: What's New and What's Coming - Spring I/O 2019
JUnit 5: What's New and What's Coming - Spring I/O 2019JUnit 5: What's New and What's Coming - Spring I/O 2019
JUnit 5: What's New and What's Coming - Spring I/O 2019
 
JUnit 5 - New Opportunities for Testing on the JVM
JUnit 5 - New Opportunities for Testing on the JVMJUnit 5 - New Opportunities for Testing on the JVM
JUnit 5 - New Opportunities for Testing on the JVM
 
Get the Most out of Testing with Spring 4.2
Get the Most out of Testing with Spring 4.2Get the Most out of Testing with Spring 4.2
Get the Most out of Testing with Spring 4.2
 
JUnit 5 - from Lambda to Alpha and beyond
JUnit 5 - from Lambda to Alpha and beyondJUnit 5 - from Lambda to Alpha and beyond
JUnit 5 - from Lambda to Alpha and beyond
 
Testing with Spring: An Introduction
Testing with Spring: An IntroductionTesting with Spring: An Introduction
Testing with Spring: An Introduction
 
Testing with Spring 4.x
Testing with Spring 4.xTesting with Spring 4.x
Testing with Spring 4.x
 
Spring Framework 4.1
Spring Framework 4.1Spring Framework 4.1
Spring Framework 4.1
 
Testing Spring MVC and REST Web Applications
Testing Spring MVC and REST Web ApplicationsTesting Spring MVC and REST Web Applications
Testing Spring MVC and REST Web Applications
 
Composable Software Architecture with Spring
Composable Software Architecture with SpringComposable Software Architecture with Spring
Composable Software Architecture with Spring
 
Testing Web Apps with Spring Framework 3.2
Testing Web Apps with Spring Framework 3.2Testing Web Apps with Spring Framework 3.2
Testing Web Apps with Spring Framework 3.2
 
Spring Framework 4.0 to 4.1
Spring Framework 4.0 to 4.1Spring Framework 4.0 to 4.1
Spring Framework 4.0 to 4.1
 
Spring Framework 4.0 - The Next Generation - Soft-Shake 2013
Spring Framework 4.0 - The Next Generation - Soft-Shake 2013Spring Framework 4.0 - The Next Generation - Soft-Shake 2013
Spring Framework 4.0 - The Next Generation - Soft-Shake 2013
 
Spring Framework 3.2 - What's New
Spring Framework 3.2 - What's NewSpring Framework 3.2 - What's New
Spring Framework 3.2 - What's New
 
Spring 3.1 and MVC Testing Support - 4Developers
Spring 3.1 and MVC Testing Support - 4DevelopersSpring 3.1 and MVC Testing Support - 4Developers
Spring 3.1 and MVC Testing Support - 4Developers
 
Effective out-of-container Integration Testing - 4Developers
Effective out-of-container Integration Testing - 4DevelopersEffective out-of-container Integration Testing - 4Developers
Effective out-of-container Integration Testing - 4Developers
 
Spring 3.1 to 3.2 in a Nutshell - SDC2012
Spring 3.1 to 3.2 in a Nutshell - SDC2012Spring 3.1 to 3.2 in a Nutshell - SDC2012
Spring 3.1 to 3.2 in a Nutshell - SDC2012
 
Spring 3.1 to 3.2 in a Nutshell - Spring I/O 2012
Spring 3.1 to 3.2 in a Nutshell - Spring I/O 2012Spring 3.1 to 3.2 in a Nutshell - Spring I/O 2012
Spring 3.1 to 3.2 in a Nutshell - Spring I/O 2012
 
Spring 3.1 and MVC Testing Support
Spring 3.1 and MVC Testing SupportSpring 3.1 and MVC Testing Support
Spring 3.1 and MVC Testing Support
 
Spring 3.1 in a Nutshell - JAX London 2011
Spring 3.1 in a Nutshell - JAX London 2011Spring 3.1 in a Nutshell - JAX London 2011
Spring 3.1 in a Nutshell - JAX London 2011
 

Recently uploaded

Jax, FL Admin Community Group 05.14.2024 Combined Deck
Jax, FL Admin Community Group 05.14.2024 Combined DeckJax, FL Admin Community Group 05.14.2024 Combined Deck
Jax, FL Admin Community Group 05.14.2024 Combined Deck
Marc Lester
 
JustNaik Solution Deck (stage bus sector)
JustNaik Solution Deck (stage bus sector)JustNaik Solution Deck (stage bus sector)
JustNaik Solution Deck (stage bus sector)
Max Lee
 

Recently uploaded (20)

GraphSummit Stockholm - Neo4j - Knowledge Graphs and Product Updates
GraphSummit Stockholm - Neo4j - Knowledge Graphs and Product UpdatesGraphSummit Stockholm - Neo4j - Knowledge Graphs and Product Updates
GraphSummit Stockholm - Neo4j - Knowledge Graphs and Product Updates
 
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
COMPUTER AND ITS COMPONENTS PPT.by naitik sharma Class 9th A mittal internati...
 
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
Tree in the Forest - Managing Details in BDD Scenarios (live2test 2024)
 
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024
Wired_2.0_CREATE YOUR ULTIMATE LEARNING ENVIRONMENT_JCON_16052024
 
Jax, FL Admin Community Group 05.14.2024 Combined Deck
Jax, FL Admin Community Group 05.14.2024 Combined DeckJax, FL Admin Community Group 05.14.2024 Combined Deck
Jax, FL Admin Community Group 05.14.2024 Combined Deck
 
Weeding your micro service landscape.pdf
Weeding your micro service landscape.pdfWeeding your micro service landscape.pdf
Weeding your micro service landscape.pdf
 
Community is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea GouletCommunity is Just as Important as Code by Andrea Goulet
Community is Just as Important as Code by Andrea Goulet
 
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi.pdf
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi.pdfStrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi.pdf
StrimziCon 2024 - Transition to Apache Kafka on Kubernetes with Strimzi.pdf
 
What need to be mastered as AI-Powered Java Developers
What need to be mastered as AI-Powered Java DevelopersWhat need to be mastered as AI-Powered Java Developers
What need to be mastered as AI-Powered Java Developers
 
Automate your OpenSIPS config tests - OpenSIPS Summit 2024
Automate your OpenSIPS config tests - OpenSIPS Summit 2024Automate your OpenSIPS config tests - OpenSIPS Summit 2024
Automate your OpenSIPS config tests - OpenSIPS Summit 2024
 
INGKA DIGITAL: Linked Metadata by Design
INGKA DIGITAL: Linked Metadata by DesignINGKA DIGITAL: Linked Metadata by Design
INGKA DIGITAL: Linked Metadata by Design
 
The Impact of PLM Software on Fashion Production
The Impact of PLM Software on Fashion ProductionThe Impact of PLM Software on Fashion Production
The Impact of PLM Software on Fashion Production
 
A Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdfA Deep Dive into Secure Product Development Frameworks.pdf
A Deep Dive into Secure Product Development Frameworks.pdf
 
How to install and activate eGrabber JobGrabber
How to install and activate eGrabber JobGrabberHow to install and activate eGrabber JobGrabber
How to install and activate eGrabber JobGrabber
 
Reinforcement Learning – a Rewards Based Approach to Machine Learning - Marko...
Reinforcement Learning – a Rewards Based Approach to Machine Learning - Marko...Reinforcement Learning – a Rewards Based Approach to Machine Learning - Marko...
Reinforcement Learning – a Rewards Based Approach to Machine Learning - Marko...
 
JustNaik Solution Deck (stage bus sector)
JustNaik Solution Deck (stage bus sector)JustNaik Solution Deck (stage bus sector)
JustNaik Solution Deck (stage bus sector)
 
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
Entropy, Software Quality, and Innovation (presented at Princeton Plasma Phys...
 
Lessons Learned from Building a Serverless Notifications System.pdf
Lessons Learned from Building a Serverless Notifications System.pdfLessons Learned from Building a Serverless Notifications System.pdf
Lessons Learned from Building a Serverless Notifications System.pdf
 
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit Milan
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit MilanWorkshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit Milan
Workshop: Enabling GenAI Breakthroughs with Knowledge Graphs - GraphSummit Milan
 
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
Anypoint Code Builder - Munich MuleSoft Meetup - 16th May 2024
 

Testing with Spring, AOT, GraalVM, and JUnit 5 - Spring I/O 2023

  • 1. Testing with Spring, AOT, GraalVM, and JUnit 5 Sam Brannen @sam_brannen
  • 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. Agenda ● JUnit 5.9, 5.10, 5.11 ● Spring 6.0 and 6.1 ● Spring AOT and GraalVM ● Demo
  • 6. JUnit Platform 1.9.x ● XML reports in new Open Test Reporting format ● https://github.com/ota4j-team/open-test-reporting ● New IterationSelector ● for selecting a subset of a test’s or container’s iterations ● Various improvements to ConsoleLauncher ● --single-color and --color-palette ● --list-engines ● JUnit Platform Suite Engine included in stand-alone JAR
  • 7. JUnit Jupiter 5.9.x (1/2) ● Configurable cleanup mode for @TempDir ● ALWAYS, ON_SUCCESS, NEVER ● New TestInstancePreConstructCallback extension API ● counterpart to existing TestInstancePreDestroyCallback ● Reusable parameter resolution for method invocations ● via ExecutableInvoker API ● accessed via ExtensionContext ● used for @MethodSource factory methods ● @MethodSource factory methods can accept arguments ● resolved by ParameterResolver extensions ● new syntax to disambiguate local factory methods
  • 8. JUnit Jupiter 5.9.x (2/2) ● Configurable thread mode for @Timeout ● INFERRED, SAME_THREAD, SEPARATE_THREAD ● @EnabledOnOs and @DisabledOnOs ● support for OS architectures ● support for FreeBSD and OpenBSD ● @EnabledInNativeImage and @DisabledInNativeImage ● enable/disable tests in GraalVM native image ● AssertionFailureBuilder ● reuse Jupiter’s logic for creating failure messages
  • 10. JUnit Platform 1.10 M1 ● Promotion of various experimental APIs to stable ● Stacktrace pruning to hide internal JUnit calls ● ConsoleLauncher ● new testfeed details mode ● new discover subcommand for test discovery without execution ● Dry-run mode for test execution ● New LauncherInterceptor SPI ● New NamespacedHierarchicalStore for use in third-party test engines
  • 11. Custom ClassLoader Arrangements ● New ReflectionSupport.tryToLoadClass(…) method that accepts an explicit ClassLoader ● ReflectionSupport.findMethod(Class<?>, String, String) ● now uses ClassLoader of the supplied class to load parameter types ● used by DiscoverySelectors.selectMethod(Class<?>, String, String) ● DiscoverySelectors methods for ClassSelector, NestedClassSelector, MethodSelector, and NestedMethodSelector that accept an explicit ClassLoader
  • 12. JUnit Jupiter 5.10 M1 ● Promotion of various experimental APIs to stable ● Failure threshold for @RepeatedTest ● New TempDirFactory SPI for customizing @TempDir ● Custom ClassLoader support for @EnabledIf, @DisabledIf, @MethodSource, and @ParameterizedTest argument conversion ● Improved configurability of parallel execution ● AnnotationBasedArgumentsProvider/AnnotationBasedArgumentConverter ● base classes for implementing ArgumentsProvider and ArgumentConverter
  • 14. Current Roadmap ● @BeforeSuite and @AfterSuite ● in JUnit Platform @Suite engine ● Extension API for customizing the ClassLoader in Jupiter ● @FieldSource for parameterized tests ● @ContainerTemplate ● analagous to @TestTemplate ● ContainerTemplateInvocationContextProvider extension API ● @ParameterizedContainer ● effectively parameterized test classes
  • 15. @FieldSource @ParameterizedTest @FieldSource("example.Utils#fruits") void test(String fruit) { /* perform assertions */ } public class Utils { public static final String[] fruits = {"apple", "banana"}; }
  • 16. @ParameterizedContainer – Field Injection @ParameterizedContainer @CsvSource({"apple, 1", "banana, 2"}) class FieldInjectionTestCase { @Parameter(0) private String fruit; @Parameter(1) private int score; @Test void test() { /* perform assertions */ } }
  • 17. @ParameterizedContainer – Constructor Injection @ParameterizedContainer @CsvSource({"apple, 1", "banana, 2"}) class ConstructorInjectionTestCase { private final String fruit; private final int score; ConstructorInjectionTestCase(String fruit, int score) { this.fruit = fruit; this.score = score; } @Test void test() { /* perform assertions */ } }
  • 18. @ParameterizedContainer – Java Record @ParameterizedContainer @CsvSource({"apple, 1", "banana, 2"}) record RecordTestCase(String fruit, int score) { @Test void test() { /* perform assertions */ } }
  • 20. Spring 6.0.x ● Module path scanning for "classpath*:" resource prefix ● useful for patched test modules with Maven ● Servlet API 6.0 baseline in Servlet mocks and MockMvc ● with Servlet 5.0 compatibility at runtime ● Assertions against Cookie attributes in CookieResultMatchers for MockMvc ● Default TestExecutionListeners enabled in JUnit 4 and TestNG base test classes ● Revised logging in the TestContext framework (TCF) ● ApplicationContextFailureProcessor SPI for processing ApplicationContext failures in the TCF ● used by Spring Boot ● Ahead of Time and GraalVM native image support
  • 21. Spring 6.1 ● Support for recording async events with @RecordApplicationEvents ● record events from threads other than main test thread ● assert events from separate thread – for example with Awaitility ● limitations in JUnit Jupiter ● Support for null in MockHttpServletResponse.setCharacterEncoding() ● New MockHttpServletRequestBuilder.setRemoteAddress() method ● Avoid repeated attempts to load failing ApplicationContext in the TestContext framework ● Potential integration with @ParameterizedContainer in JUnit Jupiter 5.11
  • 23. What are AOT and GraalVM? ● AOT ● ahead-of-time optimizations ● part of the build process ● utilized at runtime ● GraalVM – https://www.graalvm.org/ ● polyglot programming on the JVM ● native image ● compiling JVM applications to OS-specific binaries ● closed world assumptions ● no classpath ● requires runtime hints
  • 24. What is Spring AOT? ● https://docs.spring.io/spring-framework/reference/core/aot.html ● AOT optimizations meant to inspect an ApplicationContext at build time and apply decisions and discovery logic that usually happens at runtime. ● Core infrastructure in Spring Framework ● Implemented across the portfolio ● Build tools in Spring Boot ● Spring AOT optimizations are used in GraalVM native image
  • 25. AOT Support for Spring Integration Tests ● https://docs.spring.io/spring-framework/reference/testing/testcontext- framework/aot.html ● Build-time detection of Spring integration tests ● JUnit Jupiter, JUnit 4, and implicit support for TestNG etc. ● Build-time AOT processing ○ each unique test ApplicationContext will be refreshed for AOT processing ● Runtime AOT support ○ Spring integration tests use AOT-optimized ApplicationContexts
  • 26. GraalVM Native Build Tools ● https://graalvm.github.io/native-build-tools/ ● Collaboration between Oracle Labs, Spring, and Micronaut ● Build native image ● Run tests in native image using the JUnit Platform ● Plugins for Gradle and Maven ○ incorporated in Spring Boot build plugins
  • 27. Test-specific Runtime Hints ● A lot is already built-in! ● TestRuntimeHintsRegistrar ● register globally via META-INF/spring/aot.factories ● RuntimeHintsRegistrar ● register globally via META-INF/spring/aot.factories ● register locally on a test class via @ImportRuntimeHints ● Annotate test class with @Reflective or @RegisterReflectionForBinding
  • 28. Implementing Custom AOT Testing Support ● ContextLoader: implement AotContextLoader ● AOT build-time processing ● AOT runtime execution support ● Spring Framework and Spring Boot context loaders implement AotContextLoader ● TestExecutionListener: implement AotTestExecutionListener ● to participate in AOT processing ● See SqlScriptsTestExecutionListener for an example
  • 29. JUnit Support for Native Images ● @EnabledInNativeImage and @DisabledInNativeImage ○ JUnit Jupiter execution conditions ● Native Build Tools (NBT) support for JUnit Platform ● Explicit support for JUnit Jupiter and JUnit 4 ● Spring Boot 3 build tools ○ Gradle and Maven ○ Integration with NBT for testing support
  • 30. Running Spring Integration Tests in Native Image ● Maven ○ ./mvnw -PnativeTest test ● Gradle ○ ./gradlew nativeTest ● Definitely do this before deploying a native image to production ● But this can take a considerable amount of time ● So you won’t do this multiple times a day ● Consider running tests in AOT mode on the JVM first
  • 31. Disclaimer: Testing in AOT mode on JVM ● Not yet ready for prime time ○ in terms of developer experience (DX) ○ requires manual setup ● But still possible with both Maven and Gradle ○ Today I’ll show you how with Maven ● Can be useful to: ○ run tests in AOT mode on the JVM before running within a native image ○ debug failing tests first in AOT mode on the JVM
  • 32. Mini Maven / Spring AOT Tutorial ● Generate AOT test sources ○ ./mvnw clean test spring-boot:process-test-aot ● Run tests in AOT mode on JVM ○ ./mvnw -Dspring.aot.enabled=true test ● Add generated sources as “test” source folder in IDE ○ target/spring-aot/test/sources/ ○ output directory can be same as for your test code ● Add CGLIB compiled classes to output classpath in IDE ● alternative: @Configuration(proxyBeanMethods = false)
  • 33. Testing in AOT Mode ● Run test class with -Dspring.aot.enabled=true ● That’s it! ● You should see log output like: ● Loading ApplicationContext for AOT runtime for test class springio.service.ServiceTests ● Starting AOT-processed ServiceTests
  • 34. Debugging in AOT Mode ● Find mapping from test class to AOT-optimized ApplicationContext ○ org.springframework.test.context.aot.AotTestContextInitializers__Generated ○ For example, ServiceTests__TestContext001_ApplicationContextInitializer ● Set breakpoint in ApplicationContextInitializer ● Debug test class with -Dspring.aot.enabled=true