Découvrez le compte-rendu du Spring Meetup Paris de mars 2025 : optimisez vos tests Java avec JUnit 5 et boostez vos batchs Spring grâce à GraalVM Native Image. Des conseils pratiques, des exemples concrets et des retours d'expérience pour améliorer la qualité et les performances de vos applications
En tant que co-organisateurs du Spring Meetup j’ai surtout le privilège d’y participer et je vous partage aujourd’hui mes apprentissages de la session de Mars.
Pour rappel les Spring Meetups sont des événements communautaires organisés régulièrement pour les développeurs et passionnés de l'écosystème Spring. Ces rencontres permettent aux participants d'échanger, d'apprendre et de partager leurs connaissances autour des technologies Spring, Java et des bonnes pratiques de développement.
La première présentation était consacrée à l'optimisation des tests avec JUnit 5 par Juliette de Rancourt, tandis que la seconde explorait l'accélération des Spring Batch avec GraalVM et les images natives par Vincent Vauban.
Voici un compte-rendu détaillé de ces deux talks, avec des exemples concrets et des cas d'utilisation pratiques.
Dans le monde du développement Java, les tests sont une partie essentielle de notre travail quotidien. Lors du Spring Meetup Paris, nous avons eu le plaisir d'assister à une présentation captivante sur l'optimisation des tests avec JUnit 5. Cette partie résume les points clés de cette présentation et vous propose des exemples concrets pour améliorer vos tests.
Le titre de la présentation était "Comment rendre ses tests concis et évolutifs grâce à JUnit 5". Mais que signifie réellement ce titre ?
L'objectif n'était pas d'apprendre à écrire des tests ou à faire du TDD, mais plutôt de refactoriser des tests existants pour les rendre plus efficaces.
JUnit fournit des assertions basiques, mais elles ne sont pas toujours très lisibles ou pratiques à utiliser. Comparons :
AssertJ offre une syntaxe plus fluide et plus lisible, qui ressemble davantage à des phrases. De plus, les messages d'erreur sont beaucoup plus informatifs.
On peut même aller plus loin en créant nos propres assertions métier :
Cette approche permet d'avoir des assertions qui parlent le langage du métier, rendant les tests beaucoup plus expressifs.
Les tests paramétrés permettent d'exécuter le même test avec différentes valeurs d'entrée. C'est particulièrement utile pour tester plusieurs cas sans dupliquer le code.
Au lieu d'écrire deux tests séparés pour vérifier qu'un événement ne peut pas avoir une capacité de 0 ou négative, nous avons un seul test qui vérifie les deux cas.
Pour des cas plus complexes, on peut utiliser @MethodSource
:
Pour rendre les rapports de test plus lisibles, on peut personnaliser le nom affiché pour chaque cas de test :
Pour tester des paires de valeurs :
JUnit 5 peut convertir automatiquement les chaînes de caractères en différents types :
Pour les types personnalisés, on peut créer des convertisseurs :
Pour simplifier le setup des tests, on peut utiliser des ParameterResolver
pour injecter des objets directement dans nos tests :
L'implémentation du resolver pourrait ressembler à ceci :
Cette approche permet de se concentrer sur ce qui est réellement testé, en éliminant le bruit du setup.
Lorsqu'on a plusieurs implémentations d'une même interface (par exemple, des repositories pour différentes bases de données), on peut créer une interface de test :
Au lieu d'utiliser @SpringBootTest
pour tous les tests, on peut utiliser des annotations plus spécifiques qui chargent uniquement les composants nécessaires :
Pour les tests de contrôleurs, on peut utiliser les méthodes d'assertion de MockMvc :
Pour les réponses JSON complexes, on peut utiliser ApprovalTests :
Cette approche crée un fichier "approved" contenant la réponse attendue, et les tests futurs vérifieront que la réponse correspond toujours à ce fichier.
Pour tester un flux complet, on peut ordonner l'exécution des tests :
L'annotation @TestInstance(TestInstance.Lifecycle.PER_CLASS)
est importante ici, car elle garantit que la même instance de classe de test est utilisée pour tous les tests, permettant ainsi de partager l'état entre eux.
JUnit 5 offre un large éventail d'outils pour rendre nos tests plus concis et évolutifs. En utilisant ces fonctionnalités, nous pouvons :
Ces techniques nous permettent non seulement d'avoir une suite de tests plus maintenable, mais aussi d'améliorer l'expérience d'écriture des tests, les rendant plus agréables à créer et à maintenir.
N'hésitez pas à explorer la documentation de JUnit 5, qui est très complète et offre encore plus de possibilités que celles présentées ici. Comme l'a mentionné le présentateur, "la limitation est plus au niveau de notre imagination que du framework lui-même".
Compte-rendu du deuxième talk du Spring Meetup Paris - Mars 2025
Le deuxième talk du Spring Meetup Paris nous a présenté comment optimiser les performances des applications Spring Batch grâce à GraalVM et aux images natives. Cette présentation a mis en lumière des gains de performance impressionnants, particulièrement adaptés aux tâches courtes et répétitives.
Le présentateur a commencé par expliquer le contexte de sa mission : optimiser des batchs qui chargeaient environ 8000 classes à chaque démarrage, entraînant une consommation excessive de mémoire et des pics de CPU problématiques. Avec une vingtaine de batchs utilisant le même template et s'exécutant plusieurs fois par jour, l'impact sur les coûts FinOps était significatif.
C'est dans ce contexte que l'utilisation de Spring Native, sorti en 2022 avec la possibilité d'utiliser GraalVM, est apparue comme une solution prometteuse.
Une image native est un exécutable autonome qui contient tout ce dont l'application a besoin pour fonctionner, sans nécessiter de JVM séparée. Contrairement à l'approche traditionnelle où l'application Java s'exécute sur une JVM (comme HotSpot VM), une image native intègre directement le code machine compilé.
Voici les principales différences entre une application Java traditionnelle et une image native :
Application Java traditionnelle :
Image native :
Les images natives offrent plusieurs avantages significatifs :
Ces avantages sont particulièrement intéressants pour les applications qui démarrent fréquemment et s'exécutent pendant une courte durée, comme les batchs.
GraalVM est une machine virtuelle universelle qui permet d'exécuter des applications écrites dans différents langages :
Cette polyvalence en fait un outil puissant, mais c'est surtout sa capacité à compiler des applications Java en images natives qui nous intéresse ici.
La compilation d'une application Java en image native avec GraalVM suit un processus différent de la compilation Java traditionnelle :
La différence principale réside dans l'étape de compilation AOT (Ahead-of-Time) qui permet de générer du code machine avant l'exécution, plutôt que de laisser la JVM le faire à la volée.
Pour démontrer les avantages des images natives, le présentateur a créé une application Spring Batch simple de facturation avec les éléments suivants :
Billing
avec des propriétés comme ID, numéro de téléphone, année, mois, montant, etc.Le code ressemblait à ceci :
Pour compiler l'application en image native, il a fallu ajouter la dépendance spring-native
au projet :
Puis exécuter la commande de compilation :
Le processus de compilation peut prendre jusqu'à 10 minutes, ce qui est l'un des inconvénients de cette approche.
Les résultats de la démonstration ont été frappants :
Soit une amélioration d'environ 9 fois (et jusqu'à 40 fois dans certains cas, selon le présentateur).
Des benchmarks réalisés par Oracle confirment ces résultats, montrant que les images natives peuvent être jusqu'à 4 fois plus rapides que les applications Java traditionnelles pour certains workloads.
En termes de ressources, les images natives consomment également moins de mémoire et de CPU, ce qui se traduit par des économies significatives en environnement cloud.
Malgré leurs avantages, les images natives présentent certaines limitations :
Le principal défi technique vient du fait que toutes les classes doivent être connues au moment de la compilation. Les frameworks qui utilisent beaucoup la réflexion ou le chargement dynamique de classes (comme certains aspects de Spring) peuvent nécessiter une configuration spécifique.
Les images natives sont particulièrement adaptées pour :
En revanche, pour les applications à longue durée d'exécution, les avantages sont moins évidents, car la JVM traditionnelle avec son compilateur JIT peut atteindre des performances similaires après la phase d'optimisation.
L'utilisation de GraalVM et des images natives avec Spring Batch offre des avantages significatifs en termes de performance et d'utilisation des ressources, particulièrement pour les tâches courtes et répétitives.
Dans le cas présenté, cette approche a permis de résoudre efficacement le problème des 8000 classes chargées à chaque démarrage, réduisant ainsi la consommation de mémoire et les pics de CPU.
Bien que cette technologie présente encore certaines limitations et complexités, elle constitue une option très intéressante pour optimiser les applications Spring Batch et réduire les coûts FinOps dans des environnements cloud.
Comme l'a souligné le présentateur, cette approche est particulièrement pertinente pour les workloads qui démarrent fréquemment et s'exécutent pendant une courte durée, tandis que la JVM traditionnelle reste préférable pour les applications à longue durée d'exécution.
Pour en savoir plus n’hésitez pas à vous rendre sur le super site de FooJay pour avoir un exemple plus complet ou encore sur la vidéo youtube du talk
Ces deux présentations du Spring Meetup Paris de mars 2025 nous ont offert des perspectives précieuses sur l'optimisation de nos applications Java, que ce soit au niveau des tests ou des performances d'exécution.
Les Spring Meetups constituent une excellente opportunité pour rester à jour avec les dernières évolutions de l'écosystème Spring et Java, tout en échangeant avec d'autres professionnels partageant les mêmes intérêts. Ces événements sont organisés régulièrement dans différentes villes à travers le monde.
Si vous souhaitez participer aux prochains Spring Meetups ou en savoir plus sur les événements passés et à venir :
N'hésitez pas à rejoindre la communauté Spring et à participer aux prochains meetups pour continuer à enrichir vos connaissances et partager votre expertise !