LogoRRR utilise TestFX pour exécuter des tests d’intégration sur son interface utilisateur JavaFX. Ces tests garantissent que les flux principaux survivent aux nouvelles fonctionnalités, aux refactorisations et aux mises à jour de dépendances — et ils détectent des régressions que les tests unitaires ne peuvent tout simplement pas voir.
Pourquoi maintenant
Après plus de 20 versions, LogoRRR était devenu suffisamment complexe pour que les tests manuels ne soient plus suffisants. La base de code avait besoin d’un filet de sécurité. TestFX permet de piloter la fenêtre réelle de l’application — cliquer sur des boutons, ouvrir des fichiers, inspecter l’état de l’interface — depuis des méthodes de test JUnit.
La décision de quand investir dans des tests de bout en bout est toujours un compromis. En début de projet, les interfaces changent trop vite pour que les tests puissent suivre. Mais une fois que les flux principaux se stabilisent, les tests deviennent un accélérateur plutôt qu’une contrainte. Ce point d’inflexion est arrivé avec la version 24.3.0.
Implémentation
La syntaxe concise de Scala se prête naturellement à la construction d’un petit DSL de test. Chaque action atomique — ouvrir un fichier, cliquer sur le bouton de fermeture, vérifier que le panneau d’onglets est vide — devient un bloc de construction lisible :
@Test def openAndCloseTab(): Unit = {
checkForEmptyTabPane()
openFile(path)
checkForNonEmptyTabPane()
clickOn(lookup(UiNodes.LogFileHeaderTabs).query[StackPane](), MouseButton.SECONDARY)
waitAndClickVisibleItem(CloseTabMenuItem.uiNode(fileId))
checkForEmptyTabPane()
}
L’écriture des tests frontend a également forcé des améliorations dans le code de production. Une nouvelle couche Service a été ajoutée pour abstraire les entrées/sorties de fichiers et les appels de processus externes — des changements qui ont amélioré l’architecture indépendamment de tout bénéfice lié aux tests.
Ce que les tests ont détecté
- Comportement à l’arrêt de l’application — les ressources jamais correctement libérées sont devenues évidentes lors des tests
- Isolation des tests — chaque test doit initialiser et nettoyer son propre état, ce qui a exposé plusieurs hypothèses subtiles sur l’état partagé de l’interface
- Référence de performance — surveiller le temps d’exécution des tests empêche l’accumulation progressive de tests lents
Photo d’en-tête par Sora Shimazaki sur Pexels.
