Selon le rapport sur les tendances Java d'InfoQ de 2020, Quarkus a gagné en popularité, passant rapidement à l'espace Early Adopters. Le framework qui s'appelle lui-même supersonic, subatomic Java, a ajouté plus de fonctionnalités pour faciliter le développement et l'exploitation d'applications logicielles. Au cours des 17 mois qui ont suivi la sortie de Quarkus 1.0, son mode développement a ajouté la préservation de l'état dans les fonctionnalités de déploiement et de redéploiement à chaud et vise désormais à ajouter encore une autre fonctionnalité inspirée de Ruby. Quarkus 2.0 offrira aux développeurs la possibilité d'exécuter des tests de manière continue à chaque fois qu'une classe est modifiée. Cette fonctionnalité promet de fonctionner correctement dans les coulisses, avertissant le développeur si un nouveau code cassera les tests.
InfoQ s'est entretenu avec Stuart Douglas, senior principal engineer chez Red Hat, pour une meilleure compréhension de cette fonctionnalité prometteuse.
InfoQ : Quelle était la motivation pour mettre en œuvre des tests continus ? Quels avantages pensez-vous que cela apportera au processus de développement ?
Stuart Douglas : cela est en fait venu à cause d'une question sur la liste de diffusion d'un développeur qui développe principalement en Ruby, mais qui essayait Java. Il a dit qu'il aimait le rechargement en direct de Quarkus en mode quarkus:dev, mais qu'il était déçu que les tests soient si lents en comparaison, et a souligné que les développeurs de langages de script utilisent souvent des tests continus.
Je dois admettre que ma réaction initiale était simplement "c'est comme ça en Java", mais après avoir dormi dessus, j'ai réalisé que nous avions en fait tous les éléments de base dont nous avions besoin dans Quarkus pour faire nos propres tests continus; tout ce dont nous avions vraiment besoin était d'écrire un runner JUnit et de tout câbler ensemble.
Du point de vue du développeur, cela vous donne des retours presque instantanés sur les modifications que vous apportez. Dès que vous enregistrez votre code, les tests s'exécutent et vous pouvez voir si vos modifications ont été effectives. Nous utilisons une approche très ciblée pour exécuter des tests, nous n'exécutons donc que des tests que votre changement pourrait affecter, et le résultat est un cycle de rétroaction super rapide qui ne ressemble à rien de ce que j'ai jamais expérimenté avec Java. Je suis en fait déçu de ne pas pouvoir l’utiliser lorsque je travaille sur Quarkus lui-même.
Depuis le début, l'expérience des développeurs a été l'un de nos principaux objectifs dans Quarkus, ce qui l'amène au niveau supérieur. Étant donné qu'il est intégré au cœur de Quarkus, chaque utilisateur y a accès out-of-the-box. Cette fonctionnalité ne gonfle pas non plus l'application Quarkus résultante car aucun code de test ne se retrouve dans votre application finale. Cela signifie que nous pouvons créer des applications légères axées sur le cloud tout en offrant une excellente expérience aux développeurs.
InfoQ : cette nouvelle fonctionnalité fait actuellement partie de la version alpha de Quarkus. Quand Quarkus 2.0 sera-t-il disponible ? Prévoyez-vous des changements avant la sortie de la version GA ?
Stuart Douglas : à ce stade, nous envisageons la mi-juin.
Pour le moment, nous essayons d'obtenir autant de commentaires que possible de la communauté, et avons déjà apporté des modifications en fonction des commentaires que nous avons reçus. Je ne m'attends pas à ce que les fonctionnalités de base changent beaucoup d'ici la sortie, mais plus nous recevons de commentaires, plus nous serons en mesure de résoudre les problèmes. Il y a encore du travail à faire sur la façon dont nous présentons les résultats, à la fois dans la console et dans l'interface utilisateur de développement, donc ce sera probablement le changement le plus visible par l'utilisateur entre maintenant et la version finale.
InfoQ : Existe-t-il des limitations connues des tests continus ?
Stuart Douglas : je suppose que la plus grande limitation est qu'il doit exécuter tous les tests au démarrage afin de savoir quels tests exécuter lorsque le code change. Donc, si vous avez une énorme suite de tests, cela peut être un problème. Il y a des choses que nous pouvons faire pour atténuer cela, comme la mise en cache de ces informations entre les lancements, donc cela s'améliorera probablement dans les versions futures.
InfoQ : Êtes-vous satisfait du résultat jusqu'à présent ? Souhaitez-vous mettre en œuvre quelque chose différemment ?
Stuart Douglas : je pense que cela fonctionne mieux que ce que j'espérais lorsque j'ai commencé à expérimenter. Il y aura sans aucun doute des améliorations au fil du temps, mais je suis vraiment satisfait de l'architecture de base.
InfoQ : Pouvez-vous nous donner un aperçu des détails de sa mise en œuvre ? Y a-t-il quelque chose dont vous êtes particulièrement fier ?
Stuart Douglas : le premier défi lorsque le test est activé est de résoudre les artefacts de test et de créer un ClassLoader capable de charger les classes. Lorsque vous exécutez normalement votre application, des éléments tels que JUnit ne sont pas présents, nous devons donc les résoudre manuellement. Ceci est relativement complexe et doit être fait à la fois pour Maven et Gradle. Mais heureusement, nous avions déjà du code que nous utilisons pour résoudre la partie du temps de construction de nos extensions.
Ensuite, nous devons découvrir les tests, car le mode de développement a déjà suivi l'espace de travail actuel pour gérer les changements qui nécessitaient simplement l'ajout de métadonnées supplémentaires à notre modèle d'espace de travail existant. À l'aide de ces métadonnées, nous pouvons découvrir les classes de test de l'utilisateur et les charger dans notre nouveau ClassLoader. Lorsque nous chargeons les tests et les classes de l'application, nous effectuons en fait des transformations de bytecode qui nous permettent de suivre quand les méthodes sont appelées. C'est ainsi que nous savons quels tests touchent leurs classes correspondantes.
La chose suivante dont nous avions besoin était un moyen d'exécuter les tests, qui est le seul élément complètement nouveau. Cela impliquait d'écrire un runner JUnit, que je n'avais jamais regardé auparavant, mais l'API est vraiment très agréable, donc la mise en œuvre est simple. Lorsque nous exécutons les tests au démarrage, nous utilisons la transformation mentionnée ci-dessus pour suivre quels tests utilisent les classes de l'application.
Les trois éléments ci-dessus sont tout ce dont vous avez besoin pour exécuter les tests, mais nous avons également besoin d'un moyen de réexécuter les tests lors d'un changement de code. Le mode de développement prend déjà en charge la détection des fichiers modifiés et leur compilation automatique, nous avons donc simplement dû le modifier pour gérer également les tests. Lorsque les fichiers source sont modifiés, nous les compilons automatiquement et examinons les données d'utilisation des classes que nous avons collectées lors de notre premier test. À partir de là, nous pouvons déterminer tous les tests qui utilisent les classes modifiées et les exécuter automatiquement, sans exécuter de tests non pertinents.
De tout cela, le test runner est la seule partie complètement nouvelle. Tout le reste n'est qu'une amélioration d'une fonctionnalité que nous avions déjà. Ce dont je suis le plus fier est la façon dont il peut retracer exactement les tests affectés par le code. Sans cela, vous ne sauriez pas exactement quels tests exécuter après une modification.
InfoQ : Les tests continus sont-ils automatiquement activés lorsque le mode de développement est activé ?
Stuart Douglas : il est automatiquement disponible, mais vous devez appuyer sur une touche pour l'activer. Cela peut être modifié via la configuration, vous pouvez donc configurer Quarkus pour toujours utiliser des tests continus. Quarkus fournit plusieurs raccourcis clavier pour contrôler les tests continus, afin que vous puissiez rapidement suspendre/reprendre les tests, réexécuter les tests, etc.
Nous fournissons également une commande quarkus:test qui exécutera uniquement les tests et ne lancera pas le mode développement. Cela donne aux utilisateurs plus de flexibilité. Par exemple, si vous faites simplement du développement piloté par les tests, vous ne vous souciez peut-être que d'exécuter les tests.
Avec une cible pour une version GA à la mi-juin, Quarkus 2.0 offre, entre autres fonctionnalités, la possibilité d'exécuter en continu des tests pendant l'écriture du code. Semblable à la fonctionnalité de déploiement continu ajoutée dans Quarkus 1.11, les tests continus fournissent aux développeurs un retour rapide sur le code modifié, promettant de détecter rapidement les problèmes et éventuellement de les résoudre. Une partie du mode de développement de Quarkus est prête à l'emploi, ce qui permet d'apporter des modifications via la configuration. Même s'il est toujours en version alpha, seul le côté interface utilisateur de l'outil de création de rapports sera très probablement affecté, la fonctionnalité de base restant la même. Vous trouverez plus de détails sur les tests continus dans la vidéo de Douglas sur YouTube. Les développeurs sont encouragés à expérimenter cette nouvelle fonctionnalité avant la sortie GA.