You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

Testing er viktig aktivitet innen programvareutvikling og har en spesielt sentral plass i moderne smidige utviklingsmetoder. Denne siden viser hvordan JavaFX-baserte GUI kan testes vha. JUnit-påbygget TestFX.

Testing av GUI

GUI-testing handler bl.a. om å teste at ulike deler av GUI vises og aktiveres på riktig tidspunkt, at data vises av riktig del av GUI-et og på riktig måte, og at effekten av brukerens interaksjon er som forventet. Det er spesielt det siste som kompliserer GUI-testing, siden en må kunne simulere brukerens aksjoner, f.eks. bruk av tastatur og mus (bevegelser og knappetrykk). I tillegg er trådhåndtering viktig å gjøre riktig. Et rammeverk for GUI-testing trenger derfor litt spesiell funksjonalitet og rigging av testene.

TestFX

TestFX er et påbygg til JUnit-rammeverket som gjør det enklere å teste JavaFX-baserte GUI. For å bruke TestFX trenger en tre eksterne java-biblioteker, i tillegg til JUnit (versjon 4):

Disse må lastes ned og legges til kodingsprosjektet. Det enkleste er å lage en libs-mappe i prosjektet hvor du legger jar-filene og så legge dem til classpath-en med Build Path->Add to Build Path.

JavaFX-eksempel

Vi baserer oss på eksempel 4 i FXML-filer og Java-kontroller-logikk og ønsker å teste oppførselen til knappen slik den er implementert i kontroller-logikken. For å gjøre GUI-et testbart, så må vi gjøre én endring: Vi legger et fx:id-attributt til knappen, slik at vi kan få tak i den i testkoden vår. FXML-koden blir altså som følger:

<HBox xmlns:fx="http://javafx.com/fxml"
    fx:controller="javafx.fxmlexamples.Example4Controller">
    <TextField fx:id="textField" promptText="Type something here"/>
    <Button fx:id="upcaseButton" text="Click me!" onAction="#handleUpcaseAction"/>
</HBox>


 

Testing med TestFX

Når en bruker TestFX, må testklassen arve fra GuiTest (i pakken org.loadui.textfx). Dette (tror jeg) sikrer riktig trådhåndtering og oppstart av JavaFX. I motsetning til ved vanlig JUnit-tester, så bruker en ikke noen setUp-metode (JUnit 3) eller @Before-annotert metode (JUnit 4). Istedet redefineres Parent getRootNode()-metoden slik at den rigger opp (den delen av) GUI-et som skal testes og returnerer (en referanse til) rot-noden. Merk at denne ikke skal være lagt inn i noen Scene eller Stage, dette gjør TestFX for oss.

Testene skrives som vanlig (i JUnit 4) i metoder annotert med @Test. Disse kjøres selvsagt etter at getRootNode() er kalt, slik at GUI-et er ferdig rigget av TestFX. I testmetodene brukes egne metoder for 1) å få tak i spesifikk elementer i GUI-hierarkiet og 2) simulere bruker-interaksjon. F.eks. så brukes clickOn(...) til å klikke på knapper og i tekstfelt (for å gi det fokus) og type(...) for å taste inn tekst. Disse metodene er såkalt "fluent", så de kan kjedes sammen. Her er testkoden for eksemplet vårt:

public class Example5Test extends GuiTest {

	@Override
    protected Parent getRootNode() {
        try {
            return FXMLLoader.load(this.getClass().getResource("Example5Test.fxml"));
        } catch (IOException e) {
            System.err.println(e);
        }
        return null;
    }

    @Test
    public void testHandleProcess() {
        TextField textField = find("#textField");
        String text = "Example5 test";
        clickOn(textField).type(text);
        clickOn("#upcaseButton");
        assertEquals(text.toUpperCase(), textField.getText());
    }
}

Vi ser at getRootNode()-metoden inneholder den vanlige koden for å laste inn en GUI-definisjonsfil. Merk at denne metoden ikke trenger å rigge opp hele GUI-et, kun den delen som skal testes. Det er også helt greit å bruke vanlig kode for å lage GUI-hierarkiet, i stedet for å bruke FXML.

Testmetoden bruker først find-metoden (arvet fra GuiTest) for å få tak i tekstfeltet. Argumentet er en såkalt CSS-selector, og her brukes # for å referere til fx:id-attributtet fra FXML-fila. Deretter klikkes det på feltet, slik at tastaturfokuset flyttes til tekstfeltet, og den angitte teksten tastes inn. Så klikkes det på knappen, med en variant av clickOn som tar inn en selector i stedet for noden selv. Til slutt sjekkes det at teksten i tekstfeltet er endret til bare store bokstaver.

Kjøring av testen

Testen kjøres som en vanlig JUnit test. Etterhvert vil GUI-et vises og brukerinteraksjonen blir simulert etterhvert som testmetodene utføres. En snedig funksjon er muligheten for å generere skjermbilder ved feil, slik at en lettere kan se hva som gikk galt.

 

  • No labels