Das erweitere Beispiel dient zur Vermittlung eines tiefergehenden Verständnisses für die Definition und die Ausführung von Testfällen für grafische Benutzeroberflächen (GUI) unter Verwendung der API-Sammlung FEST (Fixtures for Easy Software Testing) [2]. In den folgenden Kapiteln wird die GUI, als Grundlage des erweiterten Beispiels, sowie die definierten Testfälle vorgestellt. Desweiteren werden aufgetretene Grenzen von Testfalldefinitionen aufgezeigt, erläutert und das Ergebnis in einem Fazit zusammengefasst.
Download der Beispieldateien: Zip-Archiv
Um für die Testfälle eine möglichst unspezifische jedoch komplexere Referenz-GUI zu verwenden, wurde die von Oracle als Referenz offiziell bereitgestellte Tabellen-Beispiel-Implementation [3]
als Grundlage der GUI unter Test herangezogen und an einigen Punkten erweitert. Die nachfolgende Abbildung zeigt die GUI unter Test.
Das Java-Klasse TableWindowStarter
initialisiert einen Frame, der für die spöteren FEST-Testfölle benötigt wird. Dem Frame wird ein TableWindow
-Objekt hinzugefägt, welches die zu testenden GUI-Elemente enthält.
Die TableWindow
-Klasse erbt von einem JPanel
und enthält die Tabelle zum Anzeigen der Daten sowie ein Textfeld zur Eingabe von Werten für eine Filterung und zwei weitere Textfelder für Konsolen- und Statusausgaben. Bei der
Definition der Tabelle wird - wie die folgende Abbildung zeigt - ein eigenes TableModel
(MyTableWindowModel.java
) sowie ein TableRowSorter
definiert. Das für dieses Beispiel implementierte TableModel
enthält
die Datensätzen der Tabelle und ist zudem für die Darstellung der Tabelle verantwortlich. Beispielsweise werden durch das TableModel
Boolesche Werte mit einer JCheckBox
, Strings als einfacher Text dargestellt. Desweiteren sorgt das
TableModel
dafür, dass Benutzereingaben innerhalb der Tabelle über das Konsolen-Textfeld dokumentiert werden. Über die Methode setName()
wird der Tabelle ein individueller Name zugewiesen, auf Basis dessen die Tabelle mittels
Fest in entsprechenden Testfälle identifiziert und verwendet werden kann.
Die Eingabe von Sportarten soll hingegen durch die Verwendung einer JComboBox
beschränkt werden. Dafür wird zunächst die JComboBox
mit allen zur Auswahl stehenden Sportarten definiert und im Anschluss über einen
DefaultCellEditor
- wie in der nachfolgenden Abbildung zu sehen - mit der entsprechenden Spalte der Tabelle verknüpft.
Für die Darstellung der Lieblingsfarbe als entsprechenden Farbwert innerhalb der Zelle bedarf es eines TableCellRenderer
, da das für diese Zeile als Inhalt angelegte Element der Color
-Klasse ansonsten nicht als Farbwert sondern als
herkömmlicher String (z.B. java.awt.Color [r=50,g=50,b=50]
) angezeigt und interpretiert wird. Die ColorRendererForTableWindow
-Klasse erbt von dem TableCellRenderer
, definiert demnach einen solchen und sorgt dafür, dass der
Farbwert vom Typ Color.class
korrekt interpretiert wird. Um den Farbwert anzuzeigen wird durch den CellRenderer der Hintergrund der entsprechenden Zelle eingefärbt. Zum Editieren des Farbwertes einer entsprechenden Zelle wurde mit dem ColorEditor
(ColorEditor.java
) ein eigener TableCellEditor
für diese Spalte implementiert. Der CellEditor
definiert einen Button, damit die Zelle angeklickt werden kann. Führt der Anwender bei einer Zelle eine solche Interaktion aus,
öffnet sich ein JDialog
, der wiederum einen JColorChooser
für die Auswahl einer Farbe implementiert.
Die folgende Abbildung zeigt den ColorEditor
aus Sicht des Anwenders.
Um die in überliegenden Abbildung dargestellte Funktionalität zur Verfügung zu stellen, definiert der ColorEditor
einen JButton
, welcher in der Zelle dargestellt wird. Zusätzlich implementiert der ColorEditor
das
ActionListener
-Interface um den JButton
, den JDialog
und den JColorChooser
zu steuern (siehe folgende Abbildung).
Dieses Kapitel beschreibt den Aufbau, Ablauf und die Definition der in der TableWindowTest.java
aufgestellten Testfälle für die im vorherigen Kapitel beschriebene GUI unter Test. Die Testfälle sollen lediglich die Möglichkeiten von FEST
aufzeigen und decken nicht die Gesamtheit der Menge von Testfällen unter Verwendung von FEST ab.
Die Testklasse implementiert das FestSwingTestCaseTemplate
, welches die Deklaration und die Handhabung des Robots aus dem Swing Core-Package übernimmt.
Mittels der Annotationen @BeforeClass
und @Before
werden Methoden und Variablen aufgerufen respektive deklariert, welche vor allen Testfällen oder vor jeden einzelnen Testfall aufgerufen werden. Bevor die Testfälle durchlaufen werden, soll
zunächst der FailOnThreadViolationRepaintManager
initialisiert werden. Dieser Manager lässt einen Testfall fehlschlagen, so bald dieser die Regeln des Event Dispatch Threads verletzten sollte. Innerhalb dieses Beispiels wurde vor jedem Testfall zunächst
der Robot initialisiert, die GUI unter Test gestartet und der Frame (TableWindow.java
) identifiziert werden. Um einen beliebigen Frame aufzufinden stellt FEST eine WindowFinder-Klasse
bereit über die neben Frames auch Dialoge ermittelt werden können
(vgl. [4]). Die nachfolgende Abbildung zeigt den Aufbau der beiden aufgerufenen Methoden setUpClass
und setUp
.
Die verwendeten Variablen für das Frame sowie für die Tabelle entsprechen dem FEST-eigenen Datentypen FrameFixture
sowie JTableFixture
, die über Methoden verfügen um Benutzereingaben zu simulieren, Zustände zu überprüfen und
Eigenschaftswert abzufragen (vgl. [5], [6]). FEST stellt auch weitere Fixture-Datentypen für GUI-Elemente bereit (vgl. [7]).
Mit @AfterClass
und @After
existieren Annotationen die nach allen Testfällen oder nach jedem einzelnen Testfall ausgeführt werden. Für die folgende Beispielimplementation wird nur die @After
Annotation benötigt, in der die verwendeten
Ressourcen von den Fixture-Datentypen sowie dem Robot wieder freigegeben werden.
Da die Tabelle das zentrale Element der GUI unter Test darstellt, wurde diese innerhalb der setUp
-Methode bereits einer JTableFixture
zugewiesen. Um nun zu überprüfen ob die Tabelle mit dem Namen „mainTable“ wirklich existiert kann der sehr kurze in der
nachfolgenden Abbildung dargestellte Testfall angewendet werden.
Für eine Tabelle ist es unter anderem wichtig zu erfahren, ob Einschränkungen in der Editierbarkeit auch nach Änderungen nachwievor gegeben sind. Dabei gibt es mehrere Möglichkeiten, einen solchen Testfall zu gestalten. Eine Idee wäre beispielsweise eine bestimmte Zelle
einer Spalte zu selektieren und dort verschiedene Werte einzutragen. Für den Fall dass die Zelle als nicht editierbar gelten soll, können Änderungsversuche über die IllegalStateException
abgefangen und die Nicht-Editierbarkeit als bewiesen angesehen werden.
Die folgenden Abbildung zeigt die Implementierungen der beiden Ansätze. Die testNotEditable-Methode
erwartet eine Exception, welche durch den Zusatz "expected = IllegalStateException.class"
angegeben wird und schlägt dementsprechend fehl, wenn diese ausbleibt.
Eine weitere Besonderheit enthält die Methode testEditable
. Die zu überprüfende Zelle (Sportart) wurde wie im vorherigen Kapitel beschrieben mit einem DefaultCellEditor
für ComboBoxen definiert. Es können daher nur Werte editiert werden, die ebenfalls
in der JComboBox
enthalten sind. Andernfalls schlägt der Testfall fehl.
Zur Überprüfung der korrekten Sortierung der Inhaltsdaten von Tabellen kann ein weiterer Testfall definiert werden. Die GUI unter Test bietet die Möglichkeit eine Sortierung sowohl absteigend als auch aufsteigend über den Tabellenheader vorzunehmen. Zum Testen der Sortierung wird zunächst
ein JTableHeaderFixture
angelegt, über den ein Maus-Klick auf eine Spalte der Tabelle simuliert wird. Im Anschluss muss die Sortierung durch Prüfen der angezeigten Zeilen durchgeführt werden. Die nachfolgende Abbildung zeigt die Implementation des Testfalls.
Neben der Sortierung soll mit einem weiteren Testfall die Filterung der Datensätze überprüft werden. Dazu wird zunächst die für die Eingabe von Buchstaben benötigte TextBox über das frame
identifiziert und im Anschluss entsprechende Eingaben durch die Methode enterText
durchgeführt. Die Ergebnisse der Filterung sollten vorher bekannt sein, um diese entsprechend Abfragen zu können. Dafür können die übrig gebliebenen Spalten abgefragt und auf entsprechenden Inhalt geprüft werden. Den gesamten Testfall dokumentiert die folgende Abbildung.
Für ein Überprüfen von Ausgaben aus der Status-Textbox werden über die table
Datenreihen selektiert, wobei die Textinhalte der JTextBox
einer vorher bekannten Textdefinition entsprechen sollen. Zur Ermittlung des Inhalts der JTextBox
wird wie die folgende Abbildung
zeigt über das frame
und den Namen der JTextBox
die entsprechende Textbox identifiziert und mit der requireText
-Methode überprüft.
Nicht alle der für die GUI unter Test geplanten Testfälle konnten mit FEST umgesetzt werden. In diesem Kapitel werden zwei dieser Testfälle mit ihren Einschränkungen beschrieben.
Überprüfen von ToolTips
Ein recht naheliegender Testfall ist das Überprüfen von ToolTips sowohl im TableHeader wie auch für jede Zelle. Dies gilt insbesondere bei dynamisch erzeugen ToolTips, die von Werten in der Zelle oder von Zuständen abhängen. Dynamische ToolTips können beispielsweise durch Überschreiben
der getToolTipText(MouseEvent)
-Methode einer JTable
oder durch Erweitern der getTableCellRendererComponent
-Methode eines Renderes durch den Aufruf der Methode setToolTipText()
. Beide Methoden wurden in der GUI unter Test verwendet. FEST stellt z.B. für den JTableHeaderFixture
eine Methode zum Überprüfen von ToolTips bereit, diese ruft allerdings nur die statische getToolTipText()
-Methode auf ohne die überschriebenen Varianten aufzurufen. Das Problem ist seit Oktober 2010 in dem offiziellen FEST-Diskussionsforum beschrieben worden, eine Lösung der Entwickler ist aber
bisweilen ausgeblieben (vgl. [8]).
Ein weiterer Anwendungsfall, der nicht realisiert werden konnte, war das Ändern eines Farbwertes über den JColorChooser. Die Komponente ließ sich durch einen emulierten Klick auf der Zelle starten und über den Testfall konnte darüber hinaus ein geänderter Farbwert übermittelt werden, allerdings
konnte weder ein Klick auf den OK-Button emuliert, noch die actionPerformed
-Methode des ColorEditor aufgerufen werden. Daraus folgend konnte der geänderte Farbwert nicht übernommen und der Ablauf des Anwendungsfalls nicht überprüft werden. Ein solcher Anwendungsfall könnte beispielsweise durch das Werkzeug
Marathon (vgl. [9]) realisiert werden.
Auch dieses Anwendungsbeispiel verdeutlicht den Umfang der API-Sammlung FEST und unterstreicht insbesondere das Fazit der ersten Untersuchung (vgl. [10]). Auch die anspruchsvolleren Anwendungsfälle ließen sich mittels FEST realisieren. Die nicht umsetzbaren Anwendungsfälle demonstrieren jedoch auch, dass beim
Testen von Benutzeroberflächen stets mehrere Werkzeuge eingesetzt werden sollten.
Allgemein gelingt der Einstieg in die FEST-Umgebung durch die gute Dokumentation und die vielen Anwendungsbeispiele recht schnell. Das Diskussionsforum ist zudem eine gute Anlaufstelle für auftretende Probleme.
[1] - FEST Download, http://code.google.com/p/fest/downloads/list, aufgerufen Dezember 2011.
[2] - FEST Projektseite, http://fest.easytesting.org/, aufgerufen Dezember 2011.
[3] - Oracle: How to Use Tables, http://docs.oracle.com/javase/tutorial/uiswing/components/table.html, aufgerufen Dezember 2011.
[4] - FEST: Testing Long-Duration Tasks, http://fest.codehaus.org/Testing+Long-Duration+Tasks, aufgerufen Januar 2012.
[5] - JavaDoc: Class FrameFixture, http://easytesting.org/swing/apidocs/org/fest/swing/fixture/FrameFixture.html, aufgerufen Januar 2012.
[6] - JavaDoc: Class JTableFixture, http://easytesting.org/swing/apidocs/org/fest/swing/fixture/JTableFixture.html, aufgerufen Januar 2012.
[7] - JavaDoc: Class ComponentFixture<T extends Component>, http://easytesting.org/swing/apidocs/org/fest/swing/fixture/ComponentFixture.html, aufgerufen Januar 2012.
[8] - ToolTip()-Problem im offiziellen Diskussionsforum, http://groups.google.com/group/easytesting/browse_thread/thread/447f53819616b23d/210d04230a63c174?lnk=gst, aufgerufen Dezember 2011.
[9] - Marathon testing, http://home.edvsz.fh-osnabrueck.de/skleuker/CSI/Werkzeuge/marathontesting.html, aufgerufen Dezember 2011.
[10] - FEST - Fixtures for Easy Software Testing, http://home.edvsz.fh-osnabrueck.de/skleuker/CSI/Werkzeuge/fest.html, aufgerufen Dezember 2011.