LogoRRR utilizza TestFX per eseguire test di integrazione sulla sua interfaccia utente JavaFX. Questi test garantiscono che i flussi di lavoro principali sopravvivano a nuove funzionalità, refactoring e aggiornamenti delle dipendenze, individuando regressioni che i test unitari semplicemente non possono vedere.
Perché ora
Dopo oltre 20 rilasci, LogoRRR era diventato abbastanza complesso da rendere insufficienti i soli test manuali. Il codebase aveva bisogno di una rete di sicurezza. TestFX permette di pilotare la finestra dell’applicazione reale — cliccando pulsanti, aprendo file, ispezionando lo stato dell’interfaccia utente — direttamente dai metodi di test JUnit.
La decisione su quando investire in test end-to-end è sempre un compromesso. All’inizio di un progetto, le interfacce utente cambiano troppo velocemente perché i test possano tenere il passo. Ma una volta che i flussi principali si stabilizzano, i test diventano un acceleratore piuttosto che un peso. Quel punto di svolta è arrivato con la versione 24.3.0.
Implementazione
La sintassi concisa di Scala si presta naturalmente alla creazione di un piccolo DSL per i test. Ogni azione atomica — aprire un file, cliccare sul pulsante di chiusura, verificare che il pannello delle schede sia vuoto — diventa un mattoncino leggibile:
@Test def openAndCloseTab(): Unit = {
checkForEmptyTabPane()
openFile(path)
checkForNonEmptyTabPane()
clickOn(lookup(UiNodes.LogFileHeaderTabs).query[StackPane](), MouseButton.SECONDARY)
waitAndClickVisibleItem(CloseTabMenuItem.uiNode(fileId))
checkForEmptyTabPane()
}
Scrivere test per il frontend ha forzato miglioramenti anche nel codice di produzione. È stato aggiunto un nuovo livello di Service per astrarre l’I/O dei file e le chiamate ai processi esterni — cambiamenti che hanno migliorato l’architettura indipendentemente dai benefici per i test.
Cosa hanno scoperto i test
- Comportamento di chiusura dell’applicazione — risorse che non venivano mai pulite correttamente sono diventate evidenti durante i test
- Isolamento dei test — ogni test deve impostare e distruggere il proprio stato, il che ha esposto diverse ipotesi sottili sullo stato condiviso dell’interfaccia utente
- Base di performance — monitorare il tempo di esecuzione dei test previene il lento accumulo di test lenti
Foto della testata di Sora Shimazaki su Pexels.
