QF-Test - Das Tutorial Version 4.0.6 Karlheinz Kellerer, Martin Moser, Michael Lehto, Magnus Lindström Quality First Software GmbH1 c 2002-2015 Quality First Software GmbH Copyright 16. Juli 2015 1 http://www.qfs.de Vorwort Dieses Tutorial soll als praktische Einführung in QF-Test dienen. Die Basisteile 1 und 2 stellen die Grundfunktionen von QF-Test vor und leiten Sie durch die notwendigen Schritte, um eine eigene Testsuite zu erstellen. Darüberhinaus lernen Sie Ihre Testergenisse zu analysieren, mit Hilfe des Debuggers sich schrittweise durch Ihre Tests zu bewegen und einen Überblicksreport zu erstellen. Weitere Themen sind das Konzept der Modularisierung mit Hilfe von Prozeduren und die Komponentenerkennung, die für GUI Tests von zentraler Bedeutung ist. Abhängig davon, ob es sich bei Ihrem zu testenden System um Java oder Web handelt, können Sie Teil 1 oder 2 bearbeiten oder bei Bedarf auch beide. Bei den weiterführenden Features im Teil 3 geht es um die Themen datengetriebenes Testen, Sicherstellen von Testvorbedingugen und automatisches Erstellen von Basisprozeduren. Die Bearbeitung des Basistutorials sollte, abhängig von Ihren Vorkenntnissen, ca. 4,5 bis 6,5 Stunden dauern. Die weiterführenden Features von QF-Test benötigen ca. 3 Stunden. Der geschätzte Zeitbedarf ist zu Beginn jedes Kapitels angegeben. Da dieses Tutorial zusammen mit QF-Test wächst und neue Beispiele mit neuen Features zur Verfügung gestellt werden, ist es so aufgebaut, dass Kapitel unabhängig von einander bearbeitet werden können. So können Sie später neu hinzugekommene Kapitel getrennt bearbeiten, ohne die vorherigen zu rekapitulieren. Dieses Tutorial ist auch als HTML http://www.qfs.de/de/qftest/tutorial.html. Online-Version verfügbar unter Als Alternative zum Selbststudium bietet QFS Schulungen für QF-Test an. Details dazu finden Sie unter http://www.qfs.de/de/qftest/training.html im Internet. Feedback Damit dieses Tutorial so hilfreich wie möglich wird, benötigen wir Ihre Hilfe. Es ist immer schwierig für den Entwickler eines Produktes zu erraten, welche Features für die ii Anwender wichtig sind, welche leicht zu verstehen sind und welche ein Rätsel bleiben. Darum möchten wir Sie ermuntern, uns Feedback darüber geben, was Sie in diesem Tutorial sehen möchten. Natürlich interessieren uns auch Probleme, die bei der Bearbeitung auftreten - ob Beispiele nicht funktionieren oder diese nicht den entscheidenden Punkt treffen, was auch immer. Letzten Endes ist es Ihr Feedback, das die Qualität dieses Tutorials bestimmt. Alle Ihre Kommentare, Fehlerreports und Wünsche senden Sie bitte an [email protected]. iii Inhaltsverzeichnis I Java testen mit QF-Test 1 1 Bearbeiten einer Beispiel Testsuite [30-45 Min] 2 1.1 Bevor wir anfangen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 1.2 Starten von QF-Test und Laden einer Testsuite . . . . . . . . . . . . . . . 2 1.3 Starten der Anwendung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.4 Ein erster Testfall - Mausklick Sequenz . . . . . . . . . . . . . . . . . . . 7 1.5 Einige Tipps zwischendurch . . . . . . . . . . . . . . . . . . . . . . . . . 9 1.6 Ein erster Check - Prüfen eines Textfeldes . . . . . . . . . . . . . . . . . 9 1.7 Ein zweiter Check - Zustand eines Optionsfeldes prüfen 1.8 Beenden der Applikation . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 1.9 Alles in einem Rutsch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 . . . . . . . . . 15 1.10 Reportgenerierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18 2 Erstellen einer eigenen Testsuite [45-60 Min] 21 2.1 Einführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.2 Starten der Anwendung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 2.3 Hinzufügen einer Mausklick Sequenz . . . . . . . . . . . . . . . . . . . . 31 2.4 Strukturieren einer Testsuite . . . . . . . . . . . . . . . . . . . . . . . . . 31 2.5 Überprüfen eines Textfeldes . . . . . . . . . . . . . . . . . . . . . . . . . 34 2.6 Testen von Geschäftslogik . . . . . . . . . . . . . . . . . . . . . . . . . . 38 3 Benutzen des Debuggers [30-45 Min] 40 3.1 Einführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 3.2 Starten des Debuggers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 INHALTSVERZEICHNIS iv 3.3 Das Debuggerfenster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 3.4 Unterschied zwischen aktuellem und ausgewähltem Knoten . . . . . . . 43 3.5 Sich im Einzelschritt durch einen Test oder eine Sequenz bewegen . . . 44 3.6 Knoten überspringen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47 3.7 Setzen von Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48 3.8 Lösen von Laufzeitproblemen . . . . . . . . . . . . . . . . . . . . . . . . 49 3.9 Sprung ins Protokoll . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51 4 Schreiben einer Prozedur [30-45 Min] 53 4.1 Los geht es mit einer neuen Testsuite . . . . . . . . . . . . . . . . . . . . 53 4.2 Erstellen einer Prozedur . . . . . . . . . . . . . . . . . . . . . . . . . . . 56 4.3 Hinzufügen eines Check Knotens . . . . . . . . . . . . . . . . . . . . . . 57 4.4 Über Komponenten . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60 4.5 Der Try/Catch Mechanismus . . . . . . . . . . . . . . . . . . . . . . . . . 61 4.6 Fertigstellen der Auswahllogik . . . . . . . . . . . . . . . . . . . . . . . . 64 4.7 Verbessern der Prozedur . . . . . . . . . . . . . . . . . . . . . . . . . . . 65 4.8 Aufrufen der Prozedur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66 5 Erstellen einer verallgemeinerten Prozedur [30-45 Min] 69 5.1 Anlegen eines ”Package” Knotens . . . . . . . . . . . . . . . . . . . . . . 69 5.2 Verschieben der Prozedur . . . . . . . . . . . . . . . . . . . . . . . . . . 70 5.3 Erstellen der ”deselect” Prozedur . . . . . . . . . . . . . . . . . . . . . . 70 5.4 Aufruf der Prozedur . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 72 5.5 Erstellen einer allgemeinen Prozedur . . . . . . . . . . . . . . . . . . . . 72 5.6 Angeben eines Defaultwerts . . . . . . . . . . . . . . . . . . . . . . . . . 73 5.7 Das If/Else Konstrukt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74 5.8 Aufruf der allgemeinen Prozedur . . . . . . . . . . . . . . . . . . . . . . . 76 5.9 Dokumentieren der Prozedur . . . . . . . . . . . . . . . . . . . . . . . . . 76 5.10 Abspeichern der Testsuite . . . . . . . . . . . . . . . . . . . . . . . . . . 79 6 Modularisierung [30-45 Min] 80 6.1 Erstellen der Hauptsuite . . . . . . . . . . . . . . . . . . . . . . . . . . . 80 6.2 Was gehört wohin . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 INHALTSVERZEICHNIS v 6.3 Erstellen einer Testsequenz . . . . . . . . . . . . . . . . . . . . . . . . . 82 6.4 Aufruf einer Prozedur in der Bibliothek . . . . . . . . . . . . . . . . . . . 82 6.5 Include Datei hinzufügen . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 6.6 Modularisierung für verschiedene SUTs . . . . . . . . . . . . . . . . . . . 84 7 Die Standardbibliothek [30-45 Min] 86 7.1 Das SUT zum Testen . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87 7.2 Die Standardbibliothek . . . . . . . . . . . . . . . . . . . . . . . . . . . . 88 7.3 Ausgewählte Packages und Prozeduren . . . . . . . . . . . . . . . . . . 91 7.3.1 Das Checkbox Package . . . . . . . . . . . . . . . . . . . . . . . 91 7.3.2 Das Combobox bzw. Combo Package . . . . . . . . . . . . . . . 92 7.3.3 Das General Package . . . . . . . . . . . . . . . . . . . . . . . . 92 7.3.4 Das List Package . . . . . . . . . . . . . . . . . . . . . . . . . . . 93 7.3.5 Das Menu Package 7.3.6 Das Popup Menu Package 7.3.7 Das SWT/Sash Package . . . . . . . . . . . . . . . . . . . . . . . 96 7.3.8 Das Table Package . . . . . . . . . . . . . . . . . . . . . . . . . . 97 7.3.9 Das Table/Selection Package . . . . . . . . . . . . . . . . . . . . 97 . . . . . . . . . . . . . . . . . . . . . . . . . 93 . . . . . . . . . . . . . . . . . . . . . 95 7.3.10 Das TabbedPane bzw. CTabfolder Package . . . . . . . . . . . . 98 7.3.11 Das Text Package . . . . . . . . . . . . . . . . . . . . . . . . . . 98 7.3.12 Das Tree Package . . . . . . . . . . . . . . . . . . . . . . . . . . 99 7.3.13 Das Cleanup Package . . . . . . . . . . . . . . . . . . . . . . . . 101 7.3.14 Das Swing/Filechooser Package . . . . . . . . . . . . . . . . . . 102 7.3.15 Das Swing/Optionpane Package . . . . . . . . . . . . . . . . . . 105 7.3.16 Das SWT/ColorDialog Package . . . . . . . . . . . . . . . . . . . 109 7.3.17 Das SWT/FileDialog Package . . . . . . . . . . . . . . . . . . . . 109 7.3.18 Das SWT/DirectoryDialog Package . . . . . . . . . . . . . . . . . 109 7.3.19 Das SWT/Instrument Package . . . . . . . . . . . . . . . . . . . 109 7.3.20 das AWT/Menu Package . . . . . . . . . . . . . . . . . . . . . . . 109 7.3.21 Das Run-log Package . . . . . . . . . . . . . . . . . . . . . . . . 110 7.3.22 Das Run-log.Screenshots Package . . . . . . . . . . . . . . . . . 110 7.3.23 Das Shellutils Package . . . . . . . . . . . . . . . . . . . . . . . . 110 INHALTSVERZEICHNIS vi 7.3.24 Das Utils Package . . . . . . . . . . . . . . . . . . . . . . . . . . 111 7.3.25 Das Database Package . . . . . . . . . . . . . . . . . . . . . . . 111 7.3.26 Das Check Package . . . . . . . . . . . . . . . . . . . . . . . . . 112 7.3.27 Das Databinder Package . . . . . . . . . . . . . . . . . . . . . . 112 7.3.28 Das Web Package . . . . . . . . . . . . . . . . . . . . . . . . . . 113 8 Arbeiten mit komplexen GUI Elementen [30-45 Min] 8.1 Das ”Items” Demo . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114 8.2 Eindimensionale komplexe Komponenten . . . . . . . . . . . . . . . . . . 116 8.3 Zweidimensionale komplexe Komponenten . . . . . . . . . . . . . . . . . 119 8.4 Elementknoten oder Syntax . . . . . . . . . . . . . . . . . . . . . . . . . 121 8.5 Die Bedeutung der Eindeutigkeit . . . . . . . . . . . . . . . . . . . . . . . 122 8.6 Bäume . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 123 9 Nun ist es Zeit, Ihre eigene Anwendung zu starten II 114 Web testen mit QF-Test 10 Bearbeiten einer Beispiel Testsuite [30-45 Min] 125 126 127 10.1 Starten von QF-Test und Laden einer Testsuite . . . . . . . . . . . . . . . 127 10.2 Starten des Browsers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129 10.3 Ein erster Testfall - Mausklick Sequenz . . . . . . . . . . . . . . . . . . . 133 10.4 Einige Tipps zwischendurch . . . . . . . . . . . . . . . . . . . . . . . . . 135 10.5 Ein erster Check - Prüfen eines Textfeldes . . . . . . . . . . . . . . . . . 135 10.6 Ein zweiter Check - Zustand eines Optionsfeldes prüfen . . . . . . . . . 140 10.7 Beenden der Applikation . . . . . . . . . . . . . . . . . . . . . . . . . . . 141 10.8 Alles in einem Rutsch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 10.9 Reportgenerierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 143 11 Erstellen einer eigenen Testsuite [45-60 Min] 146 11.1 Einführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 11.2 Starten der Anwendung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 146 11.3 Hinzufügen einer Mausklick Sequenz . . . . . . . . . . . . . . . . . . . . 159 INHALTSVERZEICHNIS vii 11.4 Strukturieren einer Testsuite . . . . . . . . . . . . . . . . . . . . . . . . . 160 11.5 Überprüfen eines Textfeldes . . . . . . . . . . . . . . . . . . . . . . . . . 161 12 Weitere Beispiele [5 Min] III Weiterführende Features von QF-Test 166 167 13 Einführung [5 Min] 168 14 Die Demoapplikation [5 Min] 169 15 Datengetriebenes Testen: Einen Test-case mit unterschiedlichen Testdatensätzen starten [30-45 Min] 171 15.1 Situation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 171 15.2 Die traditionelle Methode für datengetriebenes Testen . . . . . . . . . . . 172 15.3 Datentreiberkonzept . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 173 15.4 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 179 16 Abhängigkeiten: Automatisches Sicherstellen der korrekten Vorbedingungen jedes Testfalles [60 Min] 181 16.1 Einführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 181 16.2 Sicherstellen von Vorbedingungen . . . . . . . . . . . . . . . . . . . . . . 183 16.3 Verschachtelte Abhängigkeiten . . . . . . . . . . . . . . . . . . . . . . . . 187 16.4 Fehler- und Exceptionbehandlung . . . . . . . . . . . . . . . . . . . . . . 191 16.4.1 Fehlerbehandlung . . . . . . . . . . . . . . . . . . . . . . . . . . 191 16.4.2 Exception Behandlung . . . . . . . . . . . . . . . . . . . . . . . . 193 16.4.3 Zusammenfassung . . . . . . . . . . . . . . . . . . . . . . . . . . 196 16.5 Mehr zu Abhängigkeiten . . . . . . . . . . . . . . . . . . . . . . . . . . . 196 17 Automatische Erstellung von Basisprozeduren [60 Min] 198 17.1 Einführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 198 17.2 Automatische Erstellung von Prozeduren . . . . . . . . . . . . . . . . . . 200 17.3 Konfiguration der automatischen Erstellung . . . . . . . . . . . . . . . . . 205 17.3.1 Einführung . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 INHALTSVERZEICHNIS viii 17.3.2 Erstes Beispiel . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206 17.3.3 Den aktuellen Text verwenden . . . . . . . . . . . . . . . . . . . 210 17.3.4 Generieren von Container Prozeduren . . . . . . . . . . . . . . . 212 17.3.5 Der aktuelle Wert der Kindkomponente . . . . . . . . . . . . . . 214 17.3.6 Weitere Konfigurationsmöglichkeiten . . . . . . . . . . . . . . . . 217 ix Abbildungsverzeichnis 1.1 Das Fenster einer Testsuite . . . . . . . . . . . . . . . . . . . . . . . . . . 3 1.2 Der ”Testfallsatz: Options” Knoten . . . . . . . . . . . . . . . . . . . . . . 4 1.3 Der Knoten ”Vorbereitung” . . . . . . . . . . . . . . . . . . . . . . . . . . 4 1.4 Der Knoten ”Start SUT client” . . . . . . . . . . . . . . . . . . . . . . . . 5 1.5 Das ”Options Demo” . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7 1.6 Der Testfallknoten ”Clickstream” . . . . . . . . . . . . . . . . . . . . . . . 8 1.7 Die Sequenz ”Table” 8 1.8 Der zu prüfende Labeltext ”May be negative” . . . . . . . . . . . . . . . . 10 1.9 Der Testfall ”Text check” . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.10 Fehler in Knoten ”Check Text” gefunden . . . . . . . . . . . . . . . . . . 11 1.11 Protokoll für die Wiedergabe des ”Check Text” Knotens . . . . . . . . . . 12 1.12 Diagnose des fehlgeschlagenen Checks ”Check Text” . . . . . . . . . . . 13 1.13 Bildschirmabbild zum Zeitpunkt des Fehlers . . . . . . . . . . . . . . . . 14 1.14 Der ”Selected test” Knoten . . . . . . . . . . . . . . . . . . . . . . . . . . 15 1.15 Check von Auswahlfeldern im ”Options Demo” . . . . . . . . . . . . . . . 16 1.16 Die Aufräumsequenz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17 1.17 Das Protokoll des gesamten Testfallsatzes ”Options” . . . . . . . . . . . 18 1.18 Auswahldialog für die Reportgenerierung . . . . . . . . . . . . . . . . . . 19 1.19 HTML Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 2.1 Der Schnellstart-Assistent . . . . . . . . . . . . . . . . . . . . . . . . . . 22 2.2 Auswählen des SUT Typs . . . . . . . . . . . . . . . . . . . . . . . . . . . 23 2.3 Angabe des Java Programms . . . . . . . . . . . . . . . . . . . . . . . . 24 2.4 Arbeitsverzeichnis. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25 ABBILDUNGSVERZEICHNIS x 2.5 Auswahl der Jar Datei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 2.6 SWT Instrumentierung . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27 2.7 Name des Clients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 2.8 Abschließende Informationen . . . . . . . . . . . . . . . . . . . . . . . . 29 2.9 Generierte Startsequenz . . . . . . . . . . . . . . . . . . . . . . . . . . . 30 2.10 Das ”FileChooserDemo” Fenster . . . . . . . . . . . . . . . . . . . . . . . 30 2.11 Der Baum nach Aufnahme der Mausklick Sequenz . . . . . . . . . . . . 31 2.12 Beginn der Strukturierung . . . . . . . . . . . . . . . . . . . . . . . . . . 32 2.13 Dialog zur Auswahl einer Komponente . . . . . . . . . . . . . . . . . . . 33 2.14 Vorbereitungssequenz für das FileChooserDemo . . . . . . . . . . . . . 33 2.15 Der Baum nach der Neustrukturierung . . . . . . . . . . . . . . . . . . . 34 2.16 Aufnehmen eines Checks im FileChooser Fenster . . . . . . . . . . . . . 35 2.17 Der Baum nach Aufnahme und Organisieren des ”Text check” Testfalls . 36 2.18 Der Protokollbaum zum eigenen Testfallsatz . . . . . . . . . . . . . . . . 36 2.19 Ausschnitt der Detailansicht des Knotens ”Check Text” . . . . . . . . . . 37 2.20 Baum nach Einfügen des ”Check Enabled Status” Testfalls . . . . . . . . 38 3.1 Starten von Options.qft mit dem Debugger . . . . . . . . . . . . . . . 41 3.2 Das Debuggerfenster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43 3.3 Nach dem Drücken des Knopfes ”Einzelschritt ausführen” 3.4 Vorbereitung der Kommandos ”gesamten Knoten ausführen” 3.5 Vorbereitung für die Operation ”Bis Knotenende ausführen” . . . . . . . . 47 3.6 Setzen von Breakpoints . . . . . . . . . . . . . . . . . . . . . . . . . . . . 49 3.7 Auswahl des zu modifizierenden Knotens . . . . . . . . . . . . . . . . . . 50 3.8 Der modifizierte Knoten . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50 3.9 Fehler ”Keine Komponente für QF-Test ID” . . . . . . . . . . . . . . . . . 51 . . . . . . . . 45 . . . . . . 46 3.10 In das Protokoll springen . . . . . . . . . . . . . . . . . . . . . . . . . . . 52 4.1 Grundgerüst der neuen Testsuite . . . . . . . . . . . . . . . . . . . . . . 55 4.2 Kontrollkästchen in den ”Miscellaneous” Optionen des SUT . . . . . . . . 56 4.3 Hinzufügen einer Prozedur . . . . . . . . . . . . . . . . . . . . . . . . . . 57 4.4 Aufnehmen des ”Check Boolean: selected” Knotens . . . . . . . . . . . . 59 ABBILDUNGSVERZEICHNIS xi 4.5 Prozedur mit ”Check Boolean: selected” Knoten . . . . . . . . . . . . . . 60 4.6 Die Kontrollkästchen Komponente im Komponentenbaum . . . . . . . . . 61 4.7 ”Check Boolean: selected” Fehler . . . . . . . . . . . . . . . . . . . . . . 61 4.8 Im Fehlerfall Exception werfen . . . . . . . . . . . . . . . . . . . . . . . . 62 4.9 Auswählen der Exception für den ”Catch” Knoten . . . . . . . . . . . . . 63 4.10 CheckFailedException im Protokoll . . . . . . . . . . . . . . . . . . . . . 63 4.11 Prozedur mit Try/Catch Konstrukt . . . . . . . . . . . . . . . . . . . . . . 64 4.12 Prozedur mit komplettiertem Try/Catch Mechanismus . . . . . . . . . . . 65 4.13 Variable anstelle einer festen Komponente . . . . . . . . . . . . . . . . . 66 4.14 Eigenschaften des Prozeduraufrufs . . . . . . . . . . . . . . . . . . . . . 67 5.1 Das ”checkbox” Package . . . . . . . . . . . . . . . . . . . . . . . . . . . 70 5.2 Check für den Zustand ”nicht selektiert” . . . . . . . . . . . . . . . . . . . 71 5.3 Das ”checkbox” Package mit zwei Prozeduren . . . . . . . . . . . . . . . 72 5.4 Standardwert für eine Variable der Prozedur . . . . . . . . . . . . . . . . 73 5.5 Bedingung für den ”If” Knoten . . . . . . . . . . . . . . . . . . . . . . . . 74 5.6 Das If/Else Konstrukt . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 5.7 Das If/Elseif/Else Konstrukt . . . . . . . . . . . . . . . . . . . . . . . . . . 75 5.8 Prozeduraufruf für ”setState” . . . . . . . . . . . . . . . . . . . . . . . . . 76 5.9 Kommentare für die Package Dokumentation . . . . . . . . . . . . . . . . 77 5.10 Die Package Dokumentation . . . . . . . . . . . . . . . . . . . . . . . . . 78 6.1 Bibliothek utils.qft . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81 6.2 Die Sequenz ”Deselect checkbox” . . . . . . . . . . . . . . . . . . . . . . 82 6.3 ”Sequenz” Knoten mit aufgezeichnetem Mausklick . . . . . . . . . . . . . 82 6.4 Prozeduraufruf in die Suite utils.qft . . . . . . . . . . . . . . . . . . . 83 6.5 Eine Include Datei . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83 6.6 Konstante Referenz des SUT Clients . . . . . . . . . . . . . . . . . . . . 84 6.7 Variable Referenz des SUT Clients . . . . . . . . . . . . . . . . . . . . . 84 6.8 Setzen einer Variable für die gesamte Testsuite . . . . . . . . . . . . . . 85 7.1 Die Testsuite StdLibDemo.qft . . . . . . . . . . . . . . . . . . . . . . . 87 7.2 Das SUT zum Testen der Standardbibliothek . . . . . . . . . . . . . . . . 88 ABBILDUNGSVERZEICHNIS xii 7.3 Die Standardbibliothek . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89 7.4 Setzen der $(client) Variable . . . . . . . . . . . . . . . . . . . . . . . . . 90 7.5 Beispielanwendung des qfs.swing.checkbox Packages . . . . . . . 92 7.6 Beispiel eines Aufrufs von menu.setSubCheckItem 7.7 Auswählen eines Kontrollkästchens in einem Untermenü des SUTs . . . 95 7.8 Auswählen eines Untermenüeintrags in einem Kontextmenü . . . . . . . 96 7.9 Beispielaufruf von popupmenu.setSubItem . . . . . . . . . . . . . . . 96 . . . . . . . . . . 94 7.10 Beispiel für den Einsatz von text.clearArea . . . . . . . . . . . . . . 98 7.11 Beispiel für die Benutzung von tree.expand . . . . . . . . . . . . . . . 100 7.12 Aufgenommene Komponenten des Baums . . . . . . . . . . . . . . . . . 101 7.13 Beispiel für die Benutzung von qfs.swing.filechooser.selectFile . . . . . . . . . . . . . . . . 103 7.14 Aufgenommener JFileChooser Dialog und Komponenten . . . . . . . . . 104 7.15 Benutzung des NameResolvers . . . . . . . . . . . . . . . . . . . . . . . 104 7.16 Implementierung von selectFile mit generischen Komponenten . . . 105 7.17 Generische JFileChooser Komponenten in qfs.qft . . . . . . . . . . . 105 7.18 Ein JOptionPane Dialog . . . . . . . . . . . . . . . . . . . . . . . . . . 105 7.19 Generische OptionPane Komponenten in qfs.qft . . . . . . . . . . . . 108 8.1 Der Start Java SUT Client Knoten für das ”ItemsDemo” . . . . . . . . . . 115 8.2 Das Fenster des ”ItemsDemo” . . . . . . . . . . . . . . . . . . . . . . . . 116 8.3 Mausklick Operationen auf eine JList . . . . . . . . . . . . . . . . . . . . 116 8.4 Referenz auf ein JList Element . . . . . . . . . . . . . . . . . . . . . . . . 117 8.5 Der JList Element Knoten . . . . . . . . . . . . . . . . . . . . . . . . . . . 117 8.6 Die Eigenschaften des JList Elements . . . . . . . . . . . . . . . . . . . . 118 8.7 JList Element mit numerischem Index . . . . . . . . . . . . . . . . . . . . 118 8.8 JList Element mit regulärem Ausdruck als Index . . . . . . . . . . . . . . 119 8.9 Die Beispieltabelle ”sample table” im SUT . . . . . . . . . . . . . . . . . 119 8.10 Aufgenommene Mausklicks auf die JTable . . . . . . . . . . . . . . . . . 120 8.11 Gespeicherte Elementknoten für die JTable . . . . . . . . . . . . . . . . . 120 8.12 Eigenschaften eines Elementknotens der JTable . . . . . . . . . . . . . . 121 8.13 Mausklicks mit Syntax für direkten Zugriff . . . . . . . . . . . . . . . . . . 122 ABBILDUNGSVERZEICHNIS xiii 8.14 Tabelle mit identischen Elementen . . . . . . . . . . . . . . . . . . . . . . 122 8.15 Aufgenommene Mausklicks auf einen JTree . . . . . . . . . . . . . . . . 123 8.16 Direkte numerische Referenz auf einen JTree Knoten . . . . . . . . . . . 124 10.1 Das Fenster einer Testsuite . . . . . . . . . . . . . . . . . . . . . . . . . . 128 10.2 Der ”Testfallsatz: Web demo” Knoten . . . . . . . . . . . . . . . . . . . . 129 10.3 Der Knoten ”Vorbereitung: Start browser” . . . . . . . . . . . . . . . . . . 130 10.4 Der Knoten ”Browser starten” . . . . . . . . . . . . . . . . . . . . . . . . 131 10.5 Die WebDemo Seite . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133 10.6 Der Testfallknoten ”Clickstream” . . . . . . . . . . . . . . . . . . . . . . . 134 10.7 Die Sequenz ”Menu items” . . . . . . . . . . . . . . . . . . . . . . . . . . 134 10.8 Die zu prüfende Beschriftung . . . . . . . . . . . . . . . . . . . . . . . . . 136 10.9 Der Testfall ”Text check” . . . . . . . . . . . . . . . . . . . . . . . . . . . . 136 10.10 Fehler in Knoten ”Check Text” gefunden . . . . . . . . . . . . . . . . . . 137 10.11 Protokoll für die Wiedergabe des ”Text check” Knotens . . . . . . . . . . 137 10.12 Diagnose des fehlgeschlagenen Checks ”Check Text” . . . . . . . . . . . 138 10.13 Bildschirmabbild zum Zeitpunkt des Fehlers . . . . . . . . . . . . . . . . 139 10.14 Der ”Selected test” Knoten . . . . . . . . . . . . . . . . . . . . . . . . . . 140 10.15 Check von Auswahlfeldern im ”Web Demo” . . . . . . . . . . . . . . . . . 141 10.16 Die Aufräumsequenz . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 142 10.17 Das Protokoll des gesamten Testfallsatzes ”Web demo” . . . . . . . . . . 142 10.18 Auswahldialog für die Reportgenerierung . . . . . . . . . . . . . . . . . . 143 10.19 HTML Report . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 144 11.1 Der Schnellstart-Assistent . . . . . . . . . . . . . . . . . . . . . . . . . . 147 11.2 Auswählen des SUT Typs . . . . . . . . . . . . . . . . . . . . . . . . . . . 148 11.3 Angabe der URL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 149 11.4 AJAX Toolkit. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 150 11.5 Auswahl des Browsers . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151 11.6 Internet Explorer compatibility mode. . . . . . . . . . . . . . . . . . . . . 152 11.7 Java Programm für das Starten des Browser Wrappers. . . . . . . . . . . 153 11.8 Die Browser-Einstellungen . . . . . . . . . . . . . . . . . . . . . . . . . . 154 ABBILDUNGSVERZEICHNIS xiv 11.9 Name für Browser-Fenster . . . . . . . . . . . . . . . . . . . . . . . . . . 155 11.10 Name des Clients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 156 11.11 Abschließende Informationen . . . . . . . . . . . . . . . . . . . . . . . . 157 11.12 Generierte Startsequenz . . . . . . . . . . . . . . . . . . . . . . . . . . . 158 11.13 Der Baum nach Aufnahme der Mausklick Sequenz . . . . . . . . . . . . 159 11.14 Der Baum nach der Neustrukturierung . . . . . . . . . . . . . . . . . . . 161 11.15 Aufnehmen eines Text Checks . . . . . . . . . . . . . . . . . . . . . . . . 162 11.16 Der Baum nach Aufnahme und Organisieren des ”Text check” Knotens . 163 11.17 Der Protokollbaum zum eigenen Test . . . . . . . . . . . . . . . . . . . . 164 11.18 Ausschnitt der Detailansicht des Knotens ”Check Text” . . . . . . . . . . 165 14.1 Das Hauptfenster vom JCarConfigurator . . . . . . . . . . . . . . . . . . 170 15.1 Konventionelle Methode für datengetriebenes Testen . . . . . . . . . . . 172 15.2 Konventionelle Methode mit einem verschachtelten Testfallsatz . . . . . . 172 15.3 Dialog für eine Datentabelle . . . . . . . . . . . . . . . . . . . . . . . . . 174 15.4 Die gefüllte Datentabelle . . . . . . . . . . . . . . . . . . . . . . . . . . . 175 15.5 Testfallsatz mit Datentreiber . . . . . . . . . . . . . . . . . . . . . . . . . . 175 15.6 Der $(rabatt) Parameter . . . . . . . . . . . . . . . . . . . . . . . . . 176 15.7 Vollständige Datentabelle . . . . . . . . . . . . . . . . . . . . . . . . . . . 177 15.8 Name für Protokoll und Report Eigenschaft . . . . . . . . . . . . . . . . . 178 15.9 Protokoll mit unterschiedlichen Namen für Testfälle . . . . . . . . . . . . . 179 16.1 Erster Testfallsatz von dependencies_work.qft . . . . . . . . . . . . . . . . 182 16.2 Erster Testfallsatz von dependencies_work.qft . . . . . . . . . . . . . . . . 183 16.3 Beispiel Testsuite mit der ersten Abhängigkeit . . . . . . . . . . . . . . . . 184 16.4 Das Protokoll der Ausführung . . . . . . . . . . . . . . . . . . . . . . . . 184 16.5 Die neue Implementierung der Vorbereitung . . . . . . . . . . . . . . . . . 185 16.6 Die Testsuite mit Bezug auf Abhängigkeit . . . . . . . . . . . . . . . . . . . 186 16.7 Sicherstellen der Vorbedingungen für Testfall ’Rabattstufe 15’ . . . . . . . 187 16.8 ’Fahrzeugdialog geöffnet’ Abhängigkeit . . . . . . . . . . . . . . . . . . . 189 16.9 Implementierung der Testfälle . . . . . . . . . . . . . . . . . . . . . . . . 190 16.10 Protokoll von verschachtelten Abhängigkeiten . . . . . . . . . . . . . . . . 191 ABBILDUNGSVERZEICHNIS xv 16.11 Testsuite für Fehlerbehandlung . . . . . . . . . . . . . . . . . . . . . . . . . 192 16.12 Abhängigkeit mit Fehlerbehandlung . . . . . . . . . . . . . . . . . . . . . . 192 16.13 Protokoll einer Abhängigkeit mit Fehlerbehandlung . . . . . . . . . . . . . . 193 16.14 Try-Catch Knoten in Testfälle . . . . . . . . . . . . . . . . . . . . . . . . . 194 16.15 Testsuite mit Catch . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195 16.16 Protokoll der Ausführung Abhängigkeit mit Catch . . . . . . . . . . . . . . 196 17.1 Bildschirmabbild der Testsuite . . . . . . . . . . . . . . . . . . . . . . . . 200 17.2 Die Testsuite automated_procedures_work.qft . . . . . . . . . . . . . . . 201 17.3 Die aufgezeichneten Prozeduren . . . . . . . . . . . . . . . . . . . . . . 202 17.4 Die Testsuite mit den Prozeduren . . . . . . . . . . . . . . . . . . . . . . 204 17.5 Die Prozeduren für alle Panels . . . . . . . . . . . . . . . . . . . . . . . . 204 17.6 Die aktuelle Konfiguration . . . . . . . . . . . . . . . . . . . . . . . . . . . 205 17.7 Die eigene Konfigurationsdatei . . . . . . . . . . . . . . . . . . . . . . . . 206 17.8 Die checkText Prozedur . . . . . . . . . . . . . . . . . . . . . . . . . . 207 17.9 Die checkText Prozedur mit Parametern . . . . . . . . . . . . . . . . . 208 17.10 Der <COMPID> Platzhalter . . . . . . . . . . . . . . . . . . . . . . . . . . 209 17.11 Die selbst erstellten Testschritte . . . . . . . . . . . . . . . . . . . . . . . 210 17.12 Die Konfigurationsdatei mit dem aktuellen Text . . . . . . . . . . . . . . . 211 17.13 Die generierten Prozeduren mit dem aktuellen Text . . . . . . . . . . . . 211 17.14 Die Vorlage für die Containerprozedur . . . . . . . . . . . . . . . . . . . . 212 17.15 Die Verwendung von @FORCHILDREN . . . . . . . . . . . . . . . . . . . . 213 17.16 Die generierten Containerprozeduren . . . . . . . . . . . . . . . . . . . . 214 17.17 Konfiguration mit <CCURRENTVALUE> . . . . . . . . . . . . . . . . . . . . 215 17.18 Testsuite mit <CCURRENTVALUE> . . . . . . . . . . . . . . . . . . . . . . 215 17.19 Parameter für Containerprozeduren . . . . . . . . . . . . . . . . . . . . . 216 17.20 Parameter für die Containerprozedur in der Testsuite . . . . . . . . . . . 217 Teil I Java testen mit QF-Test Kapitel 1 Bearbeiten einer Beispiel Testsuite [30-45 Min] 1.1 Bevor wir anfangen Beim ersten Start von QF-Test und/oder der zu testenden Anwendung über QF-Test kann eine Sicherheitswarnung der Windows-Firewall auftreten mit der Frage, ob Java geblockt werden soll oder nicht. Da QF-Test Netzwerkprotolle für die Kommunikation mit dem SUT (System under Test) nutzt, darf dies nicht geblockt werden, um das automatisierte Testen zu ermöglichen. 1.2 Starten von QF-Test und Laden einer Testsuite Nach dem Starten von QF-Test laden Sie bitte unser erstes Beispiel. Dazu öffnen Sie den Dateiauswahl-Dialog über das Menü Datei→Öffnen... und wechseln nach qftest-4.0.6/doc/tutorial, welches sich unterhalb Ihrer QF-Test Installation befindet. Dort wählen Sie bitte die Datei Options.qft aus und öffnen diese. QF-Test präsentiert Ihnen die Testsuite wie im folgenden Bild dargestellt: 1.2. Starten von QF-Test und Laden einer Testsuite 3 Abbildung 1.1: Das Fenster der Testsuite Options.qft. Der linke Bereich des Hauptfensters enthält eine Baumstruktur, welche die Testsuite repräsentiert. Rechts befindet sich die Detailansicht des Knotens, der im Baum gerade markiert ist. (Falls die Detailansicht bei Ihnen nicht zu sehen sein sollte, aktivieren Sie diese bitte über das Menü Ansicht→Details anzeigen .) Im unteren Fensterbereich befindet sich das Terminal, welches die Standardausgaben des zu testenden Clients protokolliert. Die Anzeige des Terminals kann mittels Ansicht→Terminal→Anzeigen kontrolliert werden. Mit Hilfe des Baumes können Sie durch die Testsuite navigieren und einzelne Knoten auswählen, für die dann jeweils die Details im rechten Fensterbereich eingeblendet werden. Klicken Sie bitte doppelt auf den Knoten ”Testfallsatz: Options”, um ihn zu expandieren. Unser Testfallsatz enthält primär drei Testfälle: ”Clickstream”, ”Text check” und ”Selected test”. Umgeben werden die Testfälle von einem ”Vorbereitung”/”Aufräumen” Paar, welches ein sauberes System als Ausgangsbasis für die Testfälle garantiert. 1.3. Starten der Anwendung 4 Abbildung 1.2: Der Inhalt des Knotens ”Testfallsatz: Options”. In den folgenden Abschnitten werden wir Funktion und Zweck der einzelnen Knoten erklären. 1.3 Starten der Anwendung Zuerst wollen wir den Vorbereitungsknoten genauer unter die Lupe nehmen. Expandieren Sie ihn dazu bitte, wie im folgenden Bild gezeigt. Abbildung 1.3: Der Knoten ”Vorbereitung”. Es werden drei Kindknoten sichtbar: • ”Java SUT Client starten” startet das zu testende Programm, das System Under Test. Wir kürzen es gerne mit SUT ab. • ”Warten auf Client” wartet, bis die neue Java Virtual Machine, in welcher das SUT läuft, sich mit QF-Test verbindet. • ”Warten auf Komponente” wartet auf das Erscheinen einer bestimmten Komponente des SUT, hier dem Hauptfenster des ”Options” Dialogs. Damit kann davon ausgegangen werden, dass das SUT erfolgreich hochgelaufen und bereit für Tests 1.3. Starten der Anwendung 5 ist. Der Umgang mit Komponenten und ihre Bedeutung werden später noch genauer erläutert. Markieren Sie nun bitte den ”Java SUT Client starten” Knoten, der zum Starten des SUT verwendet wird. Abbildung 1.4: Der Knoten ”Start SUT client”. Wir wollen uns die Knotenattribute im rechten Fensterbereich genauer ansehen: • Im obersten Feld ”Client” wird ein eindeutiger Bezeichner für unsere Testapplikation definiert. Er lässt sich frei wählen und wird im Weiteren immer wieder als Referenz gebraucht. 1.3. Starten der Anwendung 6 • Das Feld ”Ausführbares Programm” wird im vorliegenden Beispiel durch die Variable ”${qftest:java}” repräsentiert. Dies entspricht dem Java Programm, das Sie während der Installation von QF-Test angegeben haben. Hier könnte aber auch eine volle Pfadangabe zu einer Java Virtual Machine stehen. Mittels des ”Programm auswählen” Knopfes lässt sich das Java Executable auch mit Hilfe eines Dateiauswahldialogs auswählen. • Das Feld ”Verzeichnis” bezeichnet das Arbeitsverzeichnis des SUT. Hier wird Ihr Heimatverzeichnis verwendet. • Die ”Klasse” enthält die Java Klasse unseres SUT, deren main() Funktion zum Starten aufgerufen wird. • Unter ”Parameter” sehen Sie ein Kommandozeilenargument für das SUT, in dem die Sprache auf Englisch gesetzt wird. Zusätzlich wird der Classpath an das SUT durchgereicht. Das ist erforderlich, da eine eigene Klasse von QF-Test als SUT verwendet wird und somit ein entsprechender Classpath benötigt wird. • Die restlichen Felder werden für das folgende Beispiel nicht benötigt und sind deshalb leer. Ganz unten befindet sich noch ein Feld ”Bemerkung”, das Kommentare aufnehmen kann. Wir wollen nun die Anwendung wirklich starten. Markieren Sie dazu bitte den Knoten ”Vorbereitung”, doch belassen Sie ihn aufgeklappt. Dann klicken Sie den Knopf ”Wie. Anschließend lässt sich der Ablauf in der Baumansicht verfolgen. Der dergabe” gerade aktive Knoten wird während der Wiedergabe durch ”->” markiert. Auch sehen Sie die Ausgaben des SUT Clients im Terminal. Nach Abschluss der Startsequenz erscheint unsere Demoapplikation ”Options Demo” am Bildschirm. Sie ist vollständig unter Kontrolle und den wachsamen Augen von QFTest. Hinweis Wenn das Options Demo auf Ihrem Bildschirm nicht zu sehen ist, oder nur kurzzeitig erscheint, dann befindet es sich vermutlich hinter dem Hauptfenster von QF-Test. Am besten positionieren Sie beide Fenster nebeneinander, so dass Sie beide zur gleichen Zeit sehen können. Sollten Sie einen Fehlerdialog erhalten, der darauf hinweist, dass sich QF-Test nicht mit dem SUT verbinden konnte, werfen Sie bitte einen Blick in das Handbuch Kapitel 3.1.3. 1.4. Ein erster Testfall - Mausklick Sequenz 7 Abbildung 1.5: Das ”Options Demo”. 1.4 Ein erster Testfall - Mausklick Sequenz Als Nächstes wollen wir einen Blick auf einen ersten Testfall werfen. Der Testfallknoten ”Clickstream” beinhaltet eine Sequenz von Mausklicks und das Ausfüllen von Textfeldern. Dadurch werden zwei einfache, aber grundlegende Möglichkeiten von QF-Test gezeigt. Wenn Sie den Testfallknoten ”Clickstream” öffnen, sehen Sie darin enthalten zwei Sequenzen: 1.4. Ein erster Testfall - Mausklick Sequenz 8 Abbildung 1.6: Der Testfallknoten ”Clickstream” besteht aus zwei Sequenzen. Um diese auszuführen, markieren Sie den ”Clickstream” Testfallknoten und drücken den ”Wiedergabe” Knopf . Die Testsequenzen werden nun automatisch im SUT abgespielt und sollten ohne Probleme durchlaufen. Das Testergebnis wird während und nach dem Testlauf in der Statuszeile am unteren Rand des QF-Test Hauptfensters angezeigt und lautet ”Keine Fehler”. Daneben gibt es auch noch Zähler für Anzahl und Ergebnis der wiedergegebenen Testfälle. In unserem Fall war das nur einer, der fehlerfrei lief, was einer Erfolgsquote von 100% entspricht. Hinweis Wenn Sie den Mauszeiger auf dem Symbol eines Testfallzählers ruhen lassen, wird Ihnen eine entsprechende Beschreibung angezeigt. Eine Auflistung aller Testfallzähler finden Sie im Kapitel Aufnahme und Wiedergabe des Handbuchs. Um anschließend nachzuvollziehen, was wir während der Wiedergabe gesehen haben, werfen wir einen Blick in die Sequenz ”Table” innerhalb des ”Clickstream” Testfalls: Abbildung 1.7: Die Sequenz ”Table” enthält Mausklicks und Texteingaben. Dort sehen wir, dass die Sequenz von zwei Mausklicks eingeleitet wird. Sie sehen auch die Koordinaten der Klicks relativ zum Nullpunkt der dahinter angegebenen Komponente. Beim ersten Klick ist das z.B. der Baumknoten mit der Bezeichnung ”Table” im JTree ”OptionGroup-tree-Tree”. Auf die Bedeutung der Syntax im Detail wird später eingegangen. Nach den Mausklicks bewirkt der ”Warten auf Komponente” Knoten, dass auf das Erscheinen eines Eingabedialogs gewartet wird, bevor im anschließenden Knoten ”Texteingabe” der Text ”String” in das Textfeld geschrieben wird. Den Rest der Sequenz sollten Sie nun alleine verstehen können. Werfen Sie ruhig auch einen Blick in die andere Testsequenz ”Tab”. Hier tauchen noch ”Tastaturevent” Knoten als Neuigkeit auf. 1.5. 1.5 Einige Tipps zwischendurch 9 Einige Tipps zwischendurch Hier zwischendurch ein kleiner Tipp, wenn Sie z.B. bei einem Knotentyp nicht genau wissen, wofür er eingesetzt wird, oder auch die Bedeutung eines seiner Attribute nicht zuordnen können. QF-Test ist mit einer kontextsensitiven Hilfe ausgestattet. Bewegen Sie den Mauszeiger zu dem Element, für das Sie Hilfe wünschen und drücken Sie die rechte Maustaste. Es erscheint das Kontextmenü, bei dem es ganz unten den Eintrag Was ist das? gibt. Wenn Sie diesen auswählen, wird das entsprechende Kapitel im Referenzteil des Handbuches in Ihren Standardbrowser geladen. (Unix-Anwender können den Browser unter Bearbeiten→Optionen... im Bereich ”Allgemein” einstellen.) So finden Sie schnell die benötigte Information. Probieren Sie es doch bitte gleich mal aus. Wenn Sie nach einem Thema oder Stichwort suchen wollen, so empfehlen wir Ihnen dies in der PDF Version des Handbuchs zu tun. Die HTML Version ist dafür nicht so gut geeignet, da sie zur besseren Navigation in einzelne Seiten aufgeteilt ist. Auf jeder HTML Seite befindet sich auch eine Verknüpfung auf die PDF Version des Handbuchs, so dass der Übergang jederzeit leicht möglich ist. 1.6 Ein erster Check - Prüfen eines Textfeldes Eines der wichtigsten Konzepte in QF-Test ist das der Checks, d.h. eine Überprüfung bestimmter Elemente im SUT. Ein ”Text Check” prüft das Vorhandensein eines Textes in einer Textfeld-Komponente des SUT. Als Beispiel für eine Überprüfung - einen Check - soll durch die nachfolgend beschriebene Sequenz die Beschriftung eines Textfeldes verifiziert werden. 1.6. Ein erster Check - Prüfen eines Textfeldes 10 Abbildung 1.8: Der zu prüfende Labeltext ”May be negative”. Wenn Sie in unserer Testapplikation ”Option Demo” im Baum auf der linken Seite den ”Miscellaneous” Knoten öffnen und darin den ”Numbers” Knoten auswählen, sehen Sie auf der rechten Seite das zweite Textfeld mit dem Label ”May be negative”. Dieser Text soll geprüft werden. Im folgenden Bild sehen Sie den zugehörigen Testfallknoten ”Text check”, im expandierten Zustand: 1.6. Ein erster Check - Prüfen eines Textfeldes 11 Abbildung 1.9: Der Testfall ”Text check”. Der Testfall besteht aus zwei Mausklicks zum Öffnen des ”Miscellaneous” Knotens und Selektieren des Eintrags ”Numbers”. Anschließend wird ein ”Check Text” Knoten benutzt, um den Labeltext zu überprüfen. Wir haben den Label ”May be negative” für das Textfeld aufgezeichnet, jedoch absichtlich den erwarteten Wert abgeändert. Sie können dies nachprüfen, indem Sie den Knoten ”Check Text” in der Testsuite markieren. Die Detailansicht des Knotens zeigt, dass der erwartete Text ”May be positive” anstatt ”May be negative” lautet. Das wird beim Ablauf des Tests zu einem Fehler führen, was aber so gewollt ist, um Ihnen zu zeigen wie man damit umgeht. Markieren Sie nun bitte den Testfall-Knoten ”Check text” und führen Sie ihn aus. Ein Dialog erscheint nach dem Ablauf mit der Meldung ”Es sind 0 Exceptions, 1 Fehler und 0 Warnungen aufgetreten”. Abbildung 1.10: QF-Test meldet einen Fehler im Knoten ”Check Text”. Zur weiteren Diagnose wollen wir uns das Protokoll ansehen. Wir können dazu direkt den Button ”Protokoll anzeigen” drücken. Alternativ kann man das Protokoll in der Test suite mittels Wiedergabe→1. ... oder der Tastenkombination Strg-L öffnen. Es wird in einem neuen Fenster angezeigt: 1.6. Ein erster Check - Prüfen eines Textfeldes 12 Abbildung 1.11: Das Protokoll für die Wiedergabe des ”Check Text” Knotens. Das Protokollfenster ähnelt im Aufbau dem einer Testsuite. Der Baum auf der linken Seite repräsentiert nun aber die zeitliche Darstellung des Testlaufs. Die Zeitachse verläuft von oben nach unten. Analog zur Testsuite befindet sich auf der rechten Seite eine Detailansicht des jeweils ausgewählten Protokollknotens im Baum. Was sofort auffällt, ist der rote Rahmen um den Wurzelknoten des Protokollbaumes. Er verrät uns, dass sich ein Fehler in einem der Kindknoten verbirgt. Die schnellste Methode, um den Fehler zu finden, bietet Bearbeiten→Nächsten Fehler finden bzw. Strg-N . Dies führt zu folgendem Bild: 1.6. Ein erster Check - Prüfen eines Textfeldes 13 Abbildung 1.12: Diagnose des fehlgeschlagenen Checks ”Check Text”. Die Detailansicht auf der rechten Seite zeigt die Abweichung zwischen erwartetem und gefundenem Text. Ein typischer Arbeitsschritt ist nun, ausgehend von dem Protokollknoten, in dem der Fehler aufgetreten ist, zurück in die Testsuite zu springen, um dort z.B. eine Anpassung im korrespondierenden Checkknoten vorzunehmen. Unter der Voraussetzung, dass der Fehler-Protokollknoten markiert ist, leistet hierbei Bearbeiten→Knoten in Testsuite finden bzw. Strg-T hervorragende Dienste. Eine Stufe weiter geht die Funktionalität des Protokollknotens mit (13) dem Titel ”Fehlgeschlagen: Check Text” in Abbildung 1.12 , auswählbar über das Kontextmenü, das man über die rechte Maustaste öffnen kann: Checkknoten mit erhaltenen Daten aktualisieren bzw. Strg-U . Eine weitere Möglichkeit zur Fehlerdiagnose tritt in Erscheinung, wenn Sie den folgenden Knoten ”Bildschirmabbild” auswählen. Dessen Detailansicht enthält ein vollständiges Abbild des Bildschirms zum Zeitpunkt, an dem der Fehler festgestellt wurde. Es kann eine große Hilfe sein, den Zustand des SUT in diesem Moment zu sehen, um die Ursache des Fehlers zu finden. Die folgende Grafik zeigt den Knoten: 1.6. Ein erster Check - Prüfen eines Textfeldes 14 Abbildung 1.13: Bildschirmabbild zum Zeitpunkt des Fehlers. Neben dem Abbild des gesamten Bildschirms speichert QF-Test auch Bilder der einzelnen Fenster des SUT. Für unser Beispiel ist dies der Knoten ”Bildschirmabbild von Fenster: Option Demo”. Diese sind dann hilfreich, falls das SUT durch eine andere Anwendung zum Fehlerzeitpunkt verdeckt ist. Hinweis Die in einem längeren Testlauf im Protokoll gesammelten Informationen können große Mengen an Arbeitsspeicher verbrauchen. Deshalb ist QF-Test so voreingestellt, dass es eine spezielle Form von kompakten Protokollen erstellt. Dabei werden nur die ca. letzten 100 Protokollknoten aufgehoben und der Rest verworfen. Informationen für Fehlerdiagnose und Reportgenerierung bleiben durchgängig erhalten. Diese Funktion ist mit der Option ”Kompakte Protokolle erstellen” über Bearbeiten→Optionen...→Protokoll→Inhalt konfigurierbar. Der Typ eines Protokolls wird auch in seinem Wurzelknoten angezeigt. Auch die Anzahl der Bildschirmabbilder, die im Protokoll gespeichert werden, ist konfigurierbar. Wenn Sie möchten, können Sie nun als kleine Übung den erwarteten Text im Knoten ”Check Text” der Testsuite wie oben beschrieben korrigieren. Wenn Sie den Checkknoten in der Testsuite anschließend nocheinmal ausführen, sollte kein Fehler mehr gemeldet werden. Machen Sie bitte zum Schluss diese Änderung mittels Bearbeiten→Rückgängig machen bzw. Strg-Z wieder rückgängig, um für die weitere Testdurchführung eine einheitliche Ausgangsbasis zu gewährleisten. 1.7. 1.7 Ein zweiter Check - Zustand eines Optionsfeldes prüfen 15 Ein zweiter Check - Zustand eines Optionsfeldes prüfen In der dritten Sequenz ”Selected Test” werden wir überprüfen, ob sich ein Optionsfeld (Radio Button) im Zustand ”ausgewählt” befindet. In der ”Options Demo” Applikation kann man interaktiv eine Anzahl von Buttons auswählen. Wir werden dieses verwenden, um sowohl einen erfolgreichen Check zu kreieren, als auch einen Check, der zu einem Fehler führt. Abbildung 1.14: Der ”Selected test” Knoten. Der Knoten ”Selected test” zeigt drei Mausklick Events und zwei Checks. Die ersten zwei Klicks bewirken ein Ausklappen des ”Miscellaneous” Knotens im ”Option Demo” Baum und das Auswählen des Eintrags ”Choices”. Danach überprüft der ”Check boolean: selected” Knoten, dass sich der vierte Radio Button nicht im Zustand ”ausgewählt” befindet. Der dritte Klick bewirkt ein Auswählen des vierten Radio Buttons und der zweite ”Check boolean: selected” Knoten überprüft erneut, dass sich dieser Button nicht im Zustand ”ausgewählt” befindet. Das ist natürlich ein Widerspruch, so dass der letzte Check offensichtlich zu einem Fehler führen wird. 1.8. Beenden der Applikation 16 Abbildung 1.15: Check von Auswahlfeldern im ”Options Demo”. Sie können nun die Check Knoten im Detail ansehen und die Sequenz auch starten. Achten Sie gegebenenfalls darauf, den ”Miscellaneous” Knoten wieder zu schließen, wenn Sie die Sequenz als Ganzes laufen lassen möchten. 1.8 Beenden der Applikation Die Aufräumsequenz wird (wie auch die Vorbereitungssequenz) nach jedem Testfall innerhalb des umschließenden Testfallsatzes ausgeführt. Sie dient dazu, die Applikation nach dem Ausführen eines Tests in einen spezifischen Zustand zu versetzen, welcher die Basis für den darauf folgenden Test bildet. Die Aufräumsequenz ist vergleichbar mit 1.9. Alles in einem Rutsch 17 ”tear-down” Methoden in Unittests. Die Aufräumsequenz ”Stop the application” versucht die Applikation auf saubere Art und Weise zu stoppen. Dazu wird der ”Cancel” Button des ”Options Demo” gedrückt. Wenn dies nicht nicht den gewünschten Erfolg bringt, wird das Beenden auf die ”harte Tour” vollzogen. Abbildung 1.16: Die Aufräumsequenz ”Stop the application”. • Den Rahmen bildet ein Konstrukt aus einem ”Try” und einem ”Catch” Knoten. • Der ”Warten auf Programmende” Knoten prüft ob das ”Options Demo” wirklich terminiert, falls nicht, wird eine ”ClientNotTerminatedException” ausgelöst. • Diese wird vom ”Catch” Knoten gefangen. • Dann beendet ein Knoten ”Programm beenden” den Client auf harte Weise. Wir haben in diesem Test einen eher ”defensiven” Aufräumknoten implementiert. Darin versuchen wir zuerst die Applikation konventionell zu beenden und nur wenn dies fehlschlägt, wird der Prozess beendet. 1.9 Alles in einem Rutsch In den vergangenen Abschnitten haben wir uns Schritt für Schritt durch die einzelnen Bereiche unserer Beispieltestsuite gearbeitet. Nun ist es an der Zeit die gesamte Suite in einem Rutsch als Ganzes ausführen zu lassen. Das könnte in der Praxis einem Regressionstest entsprechen, dem wir unser SUT unterziehen wollen. Schließen Sie bitte das ”Options Demo”, falls es aktuell läuft. Nun können Sie den Testfallsatz ”Options” markieren und ihn ausführen. Der Testlauf dauert eine knappe Minute. Dies liegt unter anderem an einer Verzögerung, die wir zur besseren Nachvollziehbarkeit eingebaut haben. Sie sehen in den Details des Testfallsatzknotens unter Standardwerte eine Variable ”delay”, die auf 500 ms definiert ist. Wenn Sie diesen Wert reduzieren, können Sie den Testlauf beschleunigen. Der Test endet mit den bekannten zwei Fehlern. 1.10. Reportgenerierung 18 Wenn Sie sich nun bitte das Protokoll ansehen, sehen Sie wie QF-Test den Test abarbeitet. Abbildung 1.17: Das Protokoll des gesamten Testfallsatzes ”Options”. Hier sieht man auch noch einmal die bereits erwähnte Eigenschaft des Testfallsatzknotens, dass vor jedem darin enthaltenen Test jeweils die Vorbereitungssequenz und danach jeweils die Aufräumsequenz abgearbeitet wird. Dadurch wird immer ein sauberer Ausgangszustand sichergestellt. 1.10 Reportgenerierung Im Qualitätssicherungsprozess ist es wichtig, Testergebnisse zu dokumentieren und auch zu archivieren. QF-Test bietet die Möglichkeit, aus Protokollen Testreports zu generieren. Wir wollen dies für das gerade aufgezeichnete Protokoll beispielhaft durchführen. Die Reportgenerierung kann im Protokollfenster über Datei→XML/HTML Report erstellen... angestoßen werden. Es erscheint ein Dialog zur weiteren Auswahl möglicher Parameter: 1.10. Reportgenerierung 19 Abbildung 1.18: Auswahldialog für die Reportgenerierung. Im ersten Feld können Sie den Dateinamen des Reports festlegen. QF-Test bietet zwei Arten von Reports - einen einfachen HTML Report und einen XML Report. Die XML Form kann der Anwender als Grundlage verwenden und sie mit Hilfe selbst geschriebener XSLT Stylesheets in einen beliebigen eigenen Report transformieren. Es gibt weitere Optionen um die Behandlung von HTML und Doctags in Kommentarfeldern und das Anzeigen des Reports nach der Generierung in einem Browser zu steuern. Sie können die Felder einfach unverändert belassen. Weitere Details finden Sie bei Bedarf im Kapitel Reports und Testdokumentation des Anwenderhandbuchs. Wir wollen uns nun einen einfachen HTML Report zu unserem letzten Testlauf erzeugen lassen. Bestätigen Sie bitte den Dialog zur Reportgenerierung (nach einem eventuellen Anpassen der Optionen) mit ”OK”. Anschließend sollte sich automatisch Ihr Browser mit einem Ergebnis äquivalent zum folgenden Bild öffnen: 1.10. Reportgenerierung 20 Abbildung 1.19: Ein HTML Report. Der Testbericht beginnt mit einer Zusammenfassung, mit allgemeinen Systeminformationen im linken Bereich, einer Legende mit der Bedeutung der verwendeten Symbole rechts und dem Gesamtergebnis darunter. In unserem Fall sind es die bekannten zwei Fehler. Auf die Zusammenfassung folgt eine Fehlerübersicht, welche alle Fehler auflistet, inklusive Ort des Auftretens (den Testfall) und beschreibender Fehlermeldung. Teil drei bildet eine Übersicht der Testfallsätze, die hier nur den ”Options” Testfallsatz enthält, da unsere Testsuite nur diesen enthält. Zum Schluss werden alle Testfälle des ”Options” Testfallsatzes mit den zugehörigen Details, wie Beschreibung, Ergebnis und Laufzeit, aufgelistet. Die Reporterstellung in QF-Test ist ein praktisches Hilfsmittel, um einen Überblick über einen Testlauf zu gewinnen und ein Dokument zu Präsentations- und Archivierungszwecken zu erstellen. Kapitel 2 Erstellen einer eigenen Testsuite [45-60 Min] 2.1 Einführung Dieses Kapitel wird Sie durch die Schritte führen, die notwendig sind, um Ihre erste eigene Testsuite zu erstellen. Die zu testende Applikation wird das ”FileChooserDemo” sein, welches Teil des Java Software Development Kit’s ist. Zur Sicherheit haben wir es jedoch (inklusive Source-Code) auch in der vorliegenden Distribution von QF-Test im Verzeichnis qftest-4.0.6/doc/tutorial/FileChooserDemo mitgeliefert. Das ”FileChooserDemo” ist eine sehr schöne Demonstration dafür, wie die Klasse ”FileChooser” in Swing angepasst werden kann, um einen spezifischen Dialog zum ”Öffnen”, ”Schließen”, ”Sichern” etc. für die eigene Applikation zu erzeugen. Wir werden es im Folgenden als SUT benutzen, um dafür eine eigene Testsuite für QF-Test zu erstellen. Dieser Teil des Tutorials erläutert folgende Schritte: Starten des SUT in QF-Test. Aufnehmen und Organisieren eines einfachen Tests. Erstellen eines Tests, welcher eine kausale Abhängigkeit von Funktionen (Geschäftslogik) in der Applikation überprüft. 2.2 Starten der Anwendung Öffnen Sie bitte eine neue, leere Testsuite mittels Datei→Neue Suite... . Bitte beachten Sie, dass die ”alte” Testsuite in einer getrennten Registerkarte geöffnet bleibt. Stellen Sie bitte sicher, dass die Detailansicht aktiv ist ( Ansicht→Details anzeigen ). In der linken Ebene des zweigeteilten Bildschirms sehen Sie den Baum, welcher die Testsuite repräsentiert. Für den dort gerade ausgewählten Knoten werden auf der rechten 2.2. Starten der Anwendung 22 Seite die Attribute im Detail angezeigt. Zu Beginn jedes Tests muss die zu testende Applikation gestartet werden. Im vorliegenden Fall soll dies das ”FileChooserDemo” aus dem Java Software Development Kit sein. bereits aus dem vorigen Kapitel kennen. Wir werden den Schnellstart-Assistenten benutzen, um eine entsprechende Startsequenz zu erzeugen. Öffnen Sie bitte den Schnellstart-Assistenten über das Extras Menü oder alternativ über den Aufnahmeknopf, wenn dieser noch das Fragezeichen zeigt. Der Assistent sollte Sie entsprechend dem folgendem erklärenden Text begrüßen. Nach einem kurzen Hallo drücken Sie bitte den ”Weiter” Knopf. Abbildung 2.1: Der Schnellstart-Assistent. Hier kann der Typ der zu testenden Applikation ausgewählt werden. Selektieren Sie bitte ”Ein Java Archiv (java -jar <archive>)” und gehen Sie weiter. 2.2. Starten der Anwendung 23 Abbildung 2.2: Auswählen des SUT Typs. Nun werden Sie nach dem Java Programm gefragt. Sie können einfach den vorgeschlagenen Wert ${qftest:java} belassen, welcher bedeutet, dass das Java benutzt wird, mit dem QF-Test selbst läuft. Sie können also einfach weiter gehen zum nächsten Schritt im Assistenten. 2.2. Starten der Anwendung 24 Abbildung 2.3: Angabe des Java Programms. Der nächste Schritt ermöglicht die Angabe eines Arbeitsverzeichnisses für die Anwendung. Da unser Demo kein solches benötigt, können Sie einfach weitergehen. 2.2. Starten der Anwendung 25 Abbildung 2.4: Arbeitsverzeichnis. Nun ist es Zeit das Java Archiv anzugeben. Für unser Beispiel wird es das FileChooserDemo.jar im Verzeichnis doc/tutorial/FileChooserDemo Ihrer QF-Test Installation sein. Sie können die Datei über den ”Verzeichnis auswählen” Knopf oberhalb des Feldes komfortabel auswählen oder direkt als Text im Feld eingeben. Eine weitere Möglichkeit (die unter Windows und Unix funtioniert) ist ${qftest:dir.version}/doc/tutorial/FileChooserDemo/FileChooserDemo.jar zu verwenden, wobei der erste Teil eine Variable ist, die zum versionsspezifischen Installationsverzeichnis von QF-Test expandiert. 2.2. Starten der Anwendung 26 Abbildung 2.5: Auswahl der Jar Datei. Den nächsten Schritt der optionalen SWT Intrumentierung können Sie einfach mit ”Weiter” überspringen, da unser FileChooserDemo Beispiel nicht auf SWT sondern auf Swing basiert. 2.2. Starten der Anwendung 27 Abbildung 2.6: SWT Instrumentierung. Fast haben wir es geschafft. Bleibt noch die Vergabe eines Namens als Referenz für unseren Client. Wir wollen ihn, nicht ganz unerwartet, ”FileChooserDemo” nennen. 2.2. Starten der Anwendung 28 Abbildung 2.7: Name des Clients. Zu guter Letzt gibt es einige Informationen, was wir zu erwarten haben, wenn der Assistent nun seine Aufgabe, eine Startsequenz zu erzeugen, abschließt und wo es Hilfe gibt im Fall von Problemen. Deaktivieren Sie bitte noch die ”Automatisch starten” Option, da wir zuerst einen Blick auf die erzeugte Startsequenz werfen wollen. Nun drücken Sie bitte den ”Fertig” Knopf. 2.2. Starten der Anwendung 29 Abbildung 2.8: Abschließende Informationen. Die generierte Startsequenz erscheint in den ”Extrasequenzen” und enthält drei Schritte: • Globale Client Variable setzen • Java SUT starten • Warten auf die Verbindung des Clients 2.2. Starten der Anwendung 30 Abbildung 2.9: Generierte Startsequenz Sie können einen Blick auf die Details der Knoten werfen und werden im wesentlichen die Werte, die Sie während der einzelnen Schritte im Assistenten eingegeben haben, den entsprechenden Knotenattributen zugewiesen finden. Nun wollen wir die Sache in Aktion sehen. Stellen Sie bitte sicher, dass der Knoten Knopf oder betätigen einfach ”Vorbereitung” ausgewählt ist und drücken Sie den die Zeilenvorschub-Taste Return . Im folgenden Bild ist das Fenster des SUT Client dargestellt, das nun erscheinen sollte. Abbildung 2.10: Das Fenster des ”FileChooserDemo”. Sollte bei Ihnen das Fenster nach einigen Sekunden nicht erscheinen, lohnt ein Blick auf das Terminal, welches u.a. Ausgaben über Fehlermeldungen beim Programmstart enthält. 2.3. 2.3 Hinzufügen einer Mausklick Sequenz 31 Hinzufügen einer Mausklick Sequenz Wir werden nun einen recht einfachen Test in Form einer Mausklick Sequenz hinzufügen. Drücken Sie dazu den ”Aufnahme” Knopf und wechseln Sie zum Fenster der ”FileChooserDemo” Applikation. Von jetzt ab wird jede Maus- oder Tastaturaktion aufgenommen. Drücken Sie bitte auf einige Buttons und wechseln Sie anschließend zurück zum QF-Test Fenster. Drücken Sie dort den Knopf. Sie finden die aufgenommene Sequenz unter dem ”Extrasequenzen” Knoten, wie im folgenden Bild dargestellt. Abbildung 2.11: Der Baum nach Aufnahme der Mausklick Sequenz. Als Namen wird standardmäßig Datum und Zeit der Erstellung verwendet. Dieser kann anschließend beliebig verändert werden. Um nun die von Ihnen erzeugte Sequenz abzuspielen, markieren Sie diese und drücken auf . Der Ablauf der Mausklick Sequenz im SUT sollte sich nun wiederholen. Diese Form des Tests ermöglicht z.B. auch die automatische Demonstration einer Applikation. In der Testanwendung wird in den meisten Fällen jedoch lediglich die zugrundeliegende Swing Implementierung der Fenster-Komponenten getestet und weniger die Geschäftslogik Ihres Programms. Im letzten Abschnitt dieses Kapitels werden wir Tests entwickeln, die den Inhalt eines Textfeldes prüfen und eine kausale Verbindung (Geschäftslogik) im ”FileChooserDemo” behandeln. Davor wollen wir jedoch aus dem Inhalt unserer Spielwiese ”Extrasequenzen” eine richtige Testsuite strukturieren. 2.4 Strukturieren einer Testsuite Die Basisstruktur unterhalb des Wurzelknotens einer Testsuite ist durch folgende Knoten festgelegt: • Eine beliebige Anzahl von ”Testfallsatz” und ”Testfall” Knoten, um funktionale Tests zu spezifizieren und zu strukturieren. 2.4. Strukturieren einer Testsuite 32 • ”Prozeduren” - hier können wiederverwertbare Sequenzen in Prozeduren organisiert werden • ”Extrasequenzen” - unsere Spielwiese für Aufnahmen etc. • ”Fenster und Komponenten” - das eigentliche Herz der Testsuite. Hier sind alle aufgenommenen Fenster und Komponenten des SUT mit ihren Eigenschaften enthalten Funktionale Testfälle werden durch ”Testfall” Knoten repräsentiert und mittels ”Testfallsatz” Knoten gruppiert und strukturiert. ”Vorbereitung” und ”Aufräumen” Knoten können Aktionen enthalten, um einen wohldefinierten Zustand vor und nach einem Testfall sicher zu stellen. Ein mögliches ”Vorbereitung/Aufräumen” Paar ist das Starten und Beenden des SUT selbst, was einen definierten Status sicherstellt. Dieser Mechanismus kann auf jeder Ebene verwendet werden, z.B das Öffnen und Schließen eines Dialogs. Wir beginnen mit dem Umbenennen des ”Testfallsatz” Knotens von ”unbenannt” in ”FileChooser Tests”. Den erscheinenden Dialog bzgl. dem Aktualisieren von Verweisen können wir einfach mit ’Ja’ beantworten. Der zweite Schritt ist, den vom Schnellstart Assitenten erzeugte Knoten ”Vorbereitung” in den ”Testfallsatz” zu verschieben, und zwar vor den enthaltenen Testfall. Das Verschieben kann mit Hilfe der Maus (Drag&Drop), des Kontextmenüs (rechte Maustaste Ausschneiden/Einfügen) oder der Tastenkombination Strg-X und Strg-V durchgeführt werden. Hinweis Bei Drag&Drop kann der Zielknoten aufgeklappt werden, indem man den Mauszeiger über dem ”+” links vom Zielknoten verweilen lässt. Der Vobereitungssequenz kann man noch eine spezifischere Beschreibung geben, a la ”FileChooserDemo starten”. Abbildung 2.12: Beginn der Strukturierung. Ein Punkt fehlt noch zur Komplettierung des ”Vorbereitung” Knotens: Nachdem sich das SUT bei QF-Test angemeldet hat, kann es noch eine Weile dauern, bis das erste 2.4. Strukturieren einer Testsuite 33 Fenster auf dem Bildschirm erscheint. Es muss sichergestellt sein, dass der eigentliche Test nicht vorher beginnt, daher muss an dieser Stelle auf das Erscheinen des Fensters gewartet werden. Fügen Sie zu diesem Zweck einen ”Warten auf Komponente” Knoten ein. Sie finden diesen unter Einfügen→Diverse Knoten→Warten auf Komponente . Wenn das SUT noch läuft, sollte das ”Client” Attribut bereits vorbelegt sein, in unserem Fall mit dem Wert ”$(client)”. Um die QF-Test component ID festzulegen, klicken Sie auf den Button oberhalb des Textfeldes. Wählen Sie in dem daraufhin erscheinenden Dialog mit den aufgezeichneten Fenstern und Komponenten den Knoten ”JFrame frameFileChooserDemo”. Abbildung 2.13: Dialog zur Auswahl einer Komponente Das Ergebnis sollte nun dem folgenden Bild entsprechen. Sie können jetzt das SUT beenden und durch Ausführen des kompletten ”Vorbereitung” Knotens neu starten. Abbildung 2.14: Vorbereitungssequenz für das FileChooserDemo. Als Nächstes gilt es, einen Testfall aus der vorher aufgezeichneten Clickstream Sequenz zu machen. Dazu müssen wir letztere aus den ”Extrasequenzen” in den unbenannten Testfall verschieben. Den ”Testfall” müssen Sie öffnen, bevor der ”Sequenz” Knoten hineingeschoben werden kann. Den Testfall wollen wir zu ’Clickstream’ umbenennen, die Sequenz zu ’Einige Clicks’. 2.5. Überprüfen eines Textfeldes 34 Zum Schluss erzeugen wir eine ”Aufräumen” Sequenz, um die Applikation zu beenden. Sie besteht aus zwei Schritten: Einer, den Client zu beenden und ein zweiter, um sicher zu stellen, dass er auch wirklich terminiert wurde. Führen Sie bitte selbstständig diese kleine Aufgabe durch. Wenn Sie fertig sind, werfen Sie zum Vergleich bitte einen Blick auf die nachfolgende Grafik. Abbildung 2.15: Der Baum nach der Neustrukturierung. Damit haben wir die wichtigsten Schritte zur Strukturierung unserer Testsuite abgeschlossen. Im folgenden Abschnitt werden wir einen ”Check” aufnehmen, um den Inhalt eines Textfeldes zu überprüfen. 2.5 Überprüfen eines Textfeldes Um das Verhalten des Clients zu überprüfen, verwenden wir ”Check” Knoten. Wir werden zuerst einen Check aufnehmen und verifizieren, dass ein Textfeld den erwarteten String beinhaltet. Der Check soll auf den Text eines Buttons im FileChooser Fenster angewendet werden. Wenn der SUT Client noch nicht läuft, so starten Sie ihn bitte und beginnen Sie mit der Aufnahme. Im FileChooserDemo drücken Sie den ”Show FileChooser” Button. Knopf in QFUm den Check aufzunehmen benützen Sie den ”Check aufnehmen” Test und wechseln wieder zum SUT. Wenn Sie sich jetzt dort mit dem Mauszeiger über Komponenten bewegen, werden diese blau umrahmt, was die aktuelle Auswahl signalisiert. Bewegen Sie bitte die Maus zum ”Öffnen” Knopf und betätigen Sie die rechte Maustaste, um einen Check aufzunehmen. Das Menü beinhaltet eine Auswahl möglicher Standard-Checks für den Button. Die folgende Abbildung zeigt die Situation: 2.5. Überprüfen eines Textfeldes 35 Abbildung 2.16: Aufnahme eines Checks im FileChooser Fenster. Wählen Sie bitte den ”Text” Check aus und beenden Sie danach die Aufnahme mit . Danach nehmen Sie eine beliebige neue Mausklick Sequenz auf und schließen dann das FileChooser Fenster. Hinweis Anstatt für die Aktivierung des Checkmodus zurück in die Testsuite zu springen, um Knopf zu drücken, können Sie auch einfach im SUT bleiben und die Taste F12 den verwenden. Sie aktiviert/deaktiviert den Modus zum Aufnehmen von Checks. Sie sollten nun die Kenntnisse besitzen, um die aufgenommenen Sequenzen in einem ”Testfall” organisieren zu können. Ihr Ergebnis können Sie mit unserer folgenden Lösung vergleichen. Hierbei haben wir zusätzlich Sequenzen in ”Testschritt” Knoten konvertiert, womit sie genauer spezifiziert sind und auch im Report sichtbar werden. 2.5. Überprüfen eines Textfeldes 36 Abbildung 2.17: Der Baum nach Aufnahme und Organisieren des ”Text check” Testfalls. Hinweis Knoten konvertieren kann man sehr einfach über den Menüpunkt Operationen Knoten konvertieren in oder über das Kontextmenü des Knotens. Wir wollen nun einen ersten richtigen Testlauf mit unserer neuen Suite durchführen. Beenden Sie dazu nun bitte den SUT Client und markieren den ’FileChooser Tests’ Testfallsatz. Führen Sie diesen durch Drücken von ”Wiedergabe” oder der Return Taste aus. Das Ergebnis des Testlaufs wird im ”Protokoll” festgehalten. Um dieses anzuschauen, können wir direkt den Button ”Protokoll anzeigen” nutzen oder wir wählen im Menü . Wiedergabe→1. ... oder aber benutzen die Tastenkombination Strg-L Abbildung 2.18: Der Protokollbaum zum eigenen Testfallsatz. Im Protokoll wird nochmal deutlich, dass die Knoten ”Vorbereitung” und ”Aufräumen” vor bzw. nach jedem Testfall ausgeführt werden, um für definierte Zustände zu sorgen. Hinweis Das Starten und Beenden der zu testenden Anwendung vor und nach jedem Testfall ist zwar ein sicherer Weg zum Herstellen sauberer Ausgangsbedingungen, jedoch auch 2.5. Überprüfen eines Textfeldes 37 ein zeitaufwendiger. In der Regel wird man versuchen das SUT nur einmal zu starten und durch andere Methoden einen definierten Ausgangszustand sicherzustellen. In diesem Testlauf traten keine Fehler oder Exceptions auf. Aber Sie sehen gelbe Rahmen um einige Knoten im Protokollbaum, welche auf Warnungen hinweisen. Im Fall des FileChooser’s werden sie durch Komponenten hervorgerufen, denen keine Namen zugewiesen sind. Wir möchten an dieser Stelle nicht weiter auf diese Warnungen eingehen, aber Sie finden ausführliche Informationen zur Wichtigkeit von Komponentennamen im Handbuch. Beim Schließen des Protokolls wird gefragt, ob Sie speichern möchten, da es nur solange verfügbar ist, bis QF-Test beendet wird. Wir werden nun einen Fehler im Knoten ”Check Text” provozieren. Sehen Sie sich dazu bitte den folgenden Ausschnitt der Detailansicht des Knotens an. Abbildung 2.19: Ausschnitt der Detailansicht des Knotens ”Check Text”. Im ”Text” Feld lässt sich ablesen, welchen Wert QF-Test in diesem Check erwartet. Um einen Fehler zu verursachen, ändern Sie diesen Text in beliebiger Weise ab. Bestätigen Sie anschließend Ihre Eingabe mit OK und führen den Test erneut aus. Ein Dialog mit dem erwarteten Resultat ”0 Exceptions, 1 Fehler, 0 Warnungen” erscheint. Wenn Sie nun das neue Protokoll öffnen, sehen Sie ein rotes Quadrat um den Knoten ”Check Text”, welches anzeigt, dass unterhalb dieses Knotens ein Fehler aufgetreten ist. Benützen Sie im Menü Bearbeiten→Nächsten Fehler finden oder die Tastenkom bination Strg-N , dann sehen Sie den von QF-Test erwarteten Text und was im Testlauf 2.6. Testen von Geschäftslogik 38 gefunden wurde. Wir werden nun einen Testfall entwerfen, der beispielhaft die Geschäftslogik in der Applikation testet. 2.6 Testen von Geschäftslogik Der überwiegende Teil unserer bisherigen Beispiele hat nicht die Logik der Applikation, sondern lediglich die zugrundeliegende Swing Implementierung des Fenster und Komponenten getestet. Um Geschäftslogik zu testen, brauchen wir einen kausalen Zusammenhang zwischen einer Aktion des Benutzers und der Reaktion der Applikation. Es gibt eine schöne, passende Konstellation im FileChooserDemo, wo ein Textfeld seinen Enabled Status beim Betätigen des ”Custom” Optionsfeldes (im linken Teil der Fensters) ändert. Für unseren Test haben wir beschlossen, eine Mausklick Sequenz zum Aktivieren des Textfeldes aufzunehmen, dann zu prüfen, dass das Textfeld wirklich aktiv ist und zum Abschluss die Applikation mit einem Druck auf den ”Öffnen” Knopf zurückzusetzen. Diese Sequenz ist ein wirklicher Aktion-Reaktion Test der Applikation, da diese zwei Komponenten innerhalb Swing keine Verbindung besitzen. Nur den Inhalt eines Textfeldes zu prüfen, ist nicht ein Test der Logik, sondern des initialen Zustandes der ganzen Applikation. Wir machen genauso weiter wie beim ”Check Text” und nehmen die Mausklick Sequenz und den Check getrennt auf. Der resultierende Baum, nach dem Neuanordnen in eine saubere Sequenz, ist im folgenden Bild gezeigt: Abbildung 2.20: Der Baum nach Einfügen des ”Check Enabled Status” Testfalls. • Die erste Sequenz drückt den ”Custom” Button und aktiviert damit das Textfeld. 2.6. Testen von Geschäftslogik 39 • Die zweite Sequenz überprüft, dass das Feld wirklich aktiv ist. Das ist ein wirklicher Test von Geschäftslogik in der Applikation, da die Verbindung zwischen dem Button und dem Textfeld außerhalb von Swing liegt. • Zum Schluss setzt die dritte Sequenz die Applikation mittels Drücken des ”Öffnen” Knopfes zurück. Sie können diesen Check auf die gleiche Weise manipulieren wie für den ”Check Text”, indem Sie in die Detailansicht gehen und das Kontrollkästchen ”Enabled Status” für den Status ausschalten. Nun wird QF-Test erwarten, dass sich das Textfeld im deaktivierten Zustand befindet, was dann während des nächsten Testlaufs zu einem Fehler führt. Wir möchten damit dieses Kapitel beenden und einen Schritt weiter in Richtung Fehlerdiagnose gehen. Hierbei stellt der Debugger ein wichtiges Werkzeug innerhalb QF-Test dar. Seine Handhabung und Möglichkeiten sollen im nächsten Abschnitt beschrieben werden. Kapitel 3 Benutzen des Debuggers [30-45 Min] 3.1 Einführung In diesem Kapitel werden wir lernen, wie der in QF-Test integrierte intuitive Debugger benutzt wird. Diejenigen unter Ihnen, die bereits Erfahrungen mit Java oder anderen Programmierumgebungen haben, werden hier Ähnlichkeiten in Funktion und Nutzen des Debuggers feststellen. Im Debuggertutorial werden wir die Testsuite Options.qft verwenden, mit der Sie ja aus den vergangenen Kapiteln bereits bestens vertraut sein sollten. Falls diese Testsuite (2) noch nicht auf Ihrem System läuft, führen Sie bitte den Startvorgang wie in Kapitel 1 beschrieben durch. 3.2 Starten des Debuggers Der QF-Test Debugger kann auf verschiedene Arten gestartet werden. Eine Möglichkeit ist es, einen Knoten oder mehrere Knoten für die Ausführung zu markieren und den Button ”Einzelschritt ausführen” oder ”gesamte Anweisung” zu drücken, oder über das Menü Debugger→Einzelschritt ausführen oder Debugger→Gesamten Knoten ausführen . 3.2. Starten des Debuggers 41 Abbildung 3.1: Auswählen eines Knotens in der Testsuite Options.qft und Starten des Debuggers. Beachten Sie, wenn Sie einen Test in Ihrer Testsuite ausführen und den ”Abspielen” Button benutzen, dass das Debuggerfenster in der Regel nicht sichtbar ist. Wenn Sie den Debugger über den Menüeintrag Debugger→Debugger aktivieren einschalten, wird er automatisch aktiviert, wenn eine nichtgefangene Exception auftritt. Wird ein benutzerdefinierter Haltepunkt erreicht, schaltet sich der Debugger in jedem Fall ein. In beiden Fällen wird die Ausführung des Tests am entsprechenden Knoten angehalten und dieser 3.3. Das Debuggerfenster 42 mit einem Pfeil markiert. 3.3 Das Debuggerfenster Der Debugger kann entweder im normalen Testsuitefenster laufen, oder in einem extra Debuggerfenster. Letzteres erhält man durch Debugger→Debuggerfenster öffnen... wenn der Debugger bereits läuft. Sie können auch einstellen, dass sich das Debuggerfenster automatisch öffnet, indem Sie dies in den globalen Einstellungen mittels Debugger→Optionen→Debuggerfenster immer öffnen festlegen. Das Debuggerfenster selbst gleicht im Aussehen dem normalen Testsuitefenster. Jedoch beinhaltet es nur die Teilmenge der Funktionen von QF-Test, die für das Debuggen benötigt werden. Die folgende Graphik zeigt das Debuggerfenster nach dem Starten des Debuggers in der Options.qft Testsuite. 3.4. Unterschied zwischen aktuellem und ausgewähltem Knoten 43 Abbildung 3.2: Das Debuggerfenster. 3.4 Unterschied zwischen ausgewähltem Knoten aktuellem und Wenn der Debugger läuft, wird ein Rahmen um das Icon des Knotens als Indikator verwendet, um den aktuell ausgeführten Knoten zu markieren. Beachten Sie auch, dass 3.5. Sich im Einzelschritt durch einen Test oder eine Sequenz bewegen 44 QF-Test die ganze Hierarchie der Ausführung, vom Eintrittspunkt hinunter bis zum aktu(43) ell ausgeführten Knoten, mit kleinen Pfeilen markiert. Siehe Abbildung 3.2 . Sie weisen dem Benutzer den Weg zum aktuellen Knoten. Sollte es im Debugger vorkommen, dass Sie den Knoten, der gerade ausgeführt wird, nicht sofort lokalisieren können, so lässt sich die Position schnell mit Hilfe des Knopbestimmen. Äquivalent geht es auch über das Menü fes ”Aktuellen Knoten finden” Debugger→Aktuellen Knoten finden . Ein ”ausgewählter” Knoten wird hervorgehoben, wie wenn Sie Ihn mit der Maus anklicken. Das kann manchmal zu Verwirrung führen, weil der aktuelle Knoten während der Debugging Sitzung auch selektiert ist. Sie werden dies aber schnell zu unterscheiden lernen. 3.5 Sich im Einzelschritt durch einen Test oder eine Sequenz bewegen Sie sind nun bereit, schrittweise durch die Knoten der Testsuite zu gehen, um das Verhalten des Debuggers zu sehen. Markieren Sie den Knoten ”Sequenz: Table” wie in (43) Abbildung 3.2 gezeigt und drücken Sie den Knopf ”Einzelschritt ausführen” . Sie sehen, dass der Debugger den aktuellen Knoten öffnet, um die enthalten Kindknoten zugänglich zu machen. Anschließend wird der erste Kindknoten selektiert, wie die folgende Graphik zeigt. 3.5. Sich im Einzelschritt durch einen Test oder eine Sequenz bewegen 45 Abbildung 3.3: Nach dem Drücken des Knopfes ”Einzelschritt ausführen”. Probieren Sie nun einige Male den ”Einzelschritt ausführen” Knopf zu drücken. Der Debugger wird den jeweiligen Knoten ausführen, dann zum nächsten springen und anschließend in den Zustand ”Pause” gehen, um das folgende Kommando abzuwarten. Nachdem wir den ”Einzelschritt” Modus gesehen haben, entriegeln Sie nun den ”Wiedergabe fortsetzen” Knopf, um die Sequenz bis zum Ende laufen zu lassen. Nach der Ausführung der ersten Sequenz der Testsuite sollte sich das Debugger Fenster vergleichbar der folgenden Graphik präsentieren: 3.5. Sich im Einzelschritt durch einen Test oder eine Sequenz bewegen 46 Abbildung 3.4: Vorbereitung der Kommandos ”gesamten Knoten ausführen”. Wenn in Ihrem Fenster der ”Sequenz: Tab” Knoten nicht selektiert ist, so wählen Sie ihn . bitte aus. Anschließend drücken Sie den Knopf ”gesamten Knoten ausführen” Diesmal reagiert der Debugger, indem er die gesamte Sequenz ausführt. Im Gegensatz zu vorher sehen Sie nun nicht die einzelnen Schritte. Während die Sequenz läuft, können Sie den Knoten ”Sequenz: Tab” aufklappen, um die einzelnen Kindknoten zu sehen. In der Tat gibt es dort verschiedene andere Sequenzen. Die Operation ”gesamten Knoten ausführen” dient also dazu, einen Knoten auszuführen, ohne sich für die Details der Einzelschritte zu interessieren. Nachdem die Ausführung des ”Sequenz: Tab” Knotens beendet wurde, ist nun der ”Sequenz: Text Check” Knoten ausgewählt. Drücken Sie den Knopf ”Einzelschritt ausführen”, so dass die Ansicht Ihres Debuggers folgender Graphik entspricht. 3.6. Knoten überspringen 47 Abbildung 3.5: Vorbereitung für die Operation ”Bis Knotenende ausführen”. Drücken Sie nun den Knopf ”Bis Knotenende ausführen” . Dies veranlasst den Debugger, die verbleibenden Knoten in der Sequenz auszuführen und den nächsten Knoten ”Sequenz: Selected test” auszuwählen. Was genau macht die Operation ”Bis zum Knotenende ausführen”? Sehr einfach - sie führt alle Knoten aus, die auf der gleichen Hierarchieebene gefunden werden wie der aktuell ausgewählte Knoten und stoppt, wenn ein Knoten gefunden wird, der höher in der Hierarchie steht. Kindknoten werden während der Aktion natürlich mit ausgeführt. Für dieses Beispiel ähnelt das ”Bis zum Knotenende ausführen” sehr der Operation ”Wiedergabe fortsetzen”. Die Aktion ist auch gleich, bis auf einen entscheidenden Unterschied. Die Operation ”Bis zum Knotenende ausführen” hält am nächsten Knoten, der höher in der Hierarchie steht an, wogegen ”Wiedergabe fortsetzen” weiterläuft. Letztere terminiert erst, wenn ein Knoten derselben Hierarchieebene gefunden wird wie die des Startknotens, bei dem die Operation begann. Wenn sich das kompliziert anhört, versuchen Sie einfach ein wenig mit den zwei Operationen in der Testsuite zu experimentieren. Sie werden schnell dahinter kommen! 3.6 Knoten überspringen Die ”Überspringen” Funktionen erweitern die Fähigkeiten des Debuggers von QF-Test in einer Weise, die über den Funktionsumfang von Standardprogrammierumgebungen hinausgeht. Wie der Name andeutet, erlauben die ”Überspringen” Operationen einen 3.7. Setzen von Breakpoints 48 oder mehrere Knoten während des Testlaufs auszulassen, d.h. weiter zu springen ohne sie auszuführen. Dies kann aus verschiedensten Gründen sinnvoll sein, sei es um schnell an eine gewisse Position in Ihrem Testablauf zu gelangen oder einen aktuell zu einem Fehler führenden Knoten zu überspringen. Bringen Sie die Testsuite wieder in den Ausgangszustand, wie im vorigen Abschnitt und betätigen Sie bitte solange den Knopf ”Einzelschritt ausführen”, bis sich der aktuelle (45) Knoten in der Sequenz wie in Abbildung 3.3 dargestellt befindet. Nun drücken Sie Button. Sie sehen sofort, dass QF-Test einfach den ”Aus Knoten herausspringen” aus der Sequenz springt, in der Sie sich gerade befinden, ohne dass die verbleibenden Knoten in der Sequenz ausgeführt werden. (46) Ihre Testsuite sollte nun, wie in Abbildung 3.4 gezeigt, aussehen. Machen Sie in diesem Zustand weiter und drücken Sie den ”Knoten überspringen” Knopf. Wir stellen ein ähnliches Verhalten fest wie bei ”Aus Knoten herausspringen”. QF-Test überspringt den ausgewählten Knoten, ohne dessen Kindknoten auszuführen. (Wenn Sie den Knoten, der übersprungen werden soll, aufklappen, sehen Sie, dass sich dort in der Tat verschiedene Sequenzen befinden, von denen keine ausgeführt wird.) Noch eine Bemerkung zu ”Knoten überspringen” und ”Aus Knoten herausspringen”: Benutzen Sie diese mit Vorsicht! Aus einer Sequenz herauszuspringen, bevor diese zu Ende gelaufen ist, kann dazu führen, dass Ihr SUT in einem unbekannten Status belassen wird, mit dem andere Sequenzen oder Tests in der Suite nicht zurechtkommen. 3.7 Setzen von Breakpoints Setzen von Breakpoints (=Haltepunkte) ist ein deterministischer Weg, Ihre Testsuite bis zu einem bestimmten Knoten auszuführen und dann anzuhalten. Anschließend ist der Debugger aktiv und Sie können mit der gewünschten Operation weitermachen. Um einen Haltepunkt zu setzen, markieren Sie einfach einenKnoten und wählen im Me . Breakpoints werden durch nü Debugger→Breakpoint an/aus oder alternativ Strg-F8 ein (B) vor dem Knoten gekennzeichnet, wie in der folgenden Graphik zu sehen ist. 3.8. Lösen von Laufzeitproblemen 49 Abbildung 3.6: Setzen von Breakpoints. Um zu sehen, wie Haltepunkte funktionieren, wählen Sie bitte den obersten Knoten Ihrer Testsuite aus und drücken Sie den ”Wiedergabe” Knopf. Um einen Breakpoint auszuschalten, selektieren Sie einfach den Knoten an dem der Haltepunkt gesetzt wurde und benutzen Sie im Menü . Das Debugger→Breakpoint an/aus oder erneut die Tastenkombination Strg-F8 Kommando Debugger→Alle Breakpoints löschen ist ebenfalls nützlich, wenn alle Haltepunkte in allen Testsuiten gelöscht werden sollen. Es gibt keine Beschränkung für die Anzahl an Breakpoints, die Sie in Ihrer Testsuite setzen können. Beachten Sie jedoch, dass Haltepunkte nicht mit Ihrer aktuellen Sitzung abgespeichert werden. Wenn Sie also Ihre Testsuite schließen, sind die Breakpoints weg. 3.8 Lösen von Laufzeitproblemen Wenn Sie beginnen Ihre eigenen Testsuiten zu erstellen und diese abzuspielen, werden Sie möglicherweise mit Problemen wie ”Keine Komponenten für QF-Test ID” oder ”Unbekannter Prozedurname” konfrontiert. Diese Probleme treten dann auf, wenn QFTest IDs bzw. Namen falsch eingegeben wurden oder sich die Namen der referenzierten Objekte selbst geändert haben. Zur Laufzeit äußert sich das Problem durch eine Unterbrechung des Testlaufs mit einer entsprechenden Fehlermeldung von QF-Test. Dies eröffnet uns die Chance, eines der wichtigsten Features des Debuggers in QFTest zu demonstrieren: Die Fähigkeit, solche Fehler direkt zur Laufzeit während der Ausführung Ihrer Testsuite zu korrigieren. Wir wollen als Erstes Ihre Testsuite dazu veranlassen, eine Exception zu werfen, indem 3.8. Lösen von Laufzeitproblemen 50 wir sie auf eine unbekannte Komponente treffen lassen. Ändern Sie in einer beliebigen Komponente die QF-Test ID in einer Weise ab, dass diese offensichtlich falsch ist. Für dieses Beispiel haben wir den ersten Knoten unter der Sequenz ”Table”, die wir in (49) Abbildung 3.6 benutzt haben, ausgewählt Abbildung 3.7: Auswahl des zu modifizierenden Knotens. und die QF-Test component ID modifiziert, so dass sie sich folgendermaßen darstellt: Abbildung 3.8: Der modifizierte Knoten. Um das Feld QF-Test component ID zu editieren, selektieren Sie den Knoten im Baum und wählen im Menü Bearbeiten→Eigenschaften... oder editieren Sie einfach das Feld in der Detailansicht (aktivierbar mittels Ansicht→Details anzeigen ). Bestätigen Sie Ihre Änderung mit dem OK Knopf. Hier wird Ihnen eine Warnung präsentiert, dass die eingegebene QF-Test ID nicht gültig ist. Das ist gut so! Es ist QF-Test’s Weg, Probleme bereits im Vorfeld zu finden. Jedoch wollen wir in diesem Beispiel eine inkorrekte Referenz erzeugen, so dass Sie bitte den ”falschen” Eintrag belassen. Wir können nun die modifizierte Testsuite ausführen. Wählen Sie bitte den Knoten ”Test: Clickstream” und drücken Sie den Knopf ”Ausführen”. Der Test stoppt prompt mit dem Fehlerdialog: 3.9. Sprung ins Protokoll 51 Abbildung 3.9: Keine Komponente für QF-Test ID. Drücken Sie den OK Button, um den Dialog zu schließen. Nun sehen Sie, dass die Ausführung der Testsuite an dem modifizierten Knoten unterbrochen wurde. Der Debugger ist aktiv und wartet auf weitere Befehle. Möchten Sie den ”Problemknoten” überspringen, den Testlauf komplett beenden um das Problem tiefer zu analysieren oder den Knoten direkt verändern und den Testlauf fortsetzen? Wir wählen die letzte Alternative (da wir ja bereits wissen, was zu tun ist). In dem sich immer noch im Wartezustand befindlichen Debugger können Sie nun das Feld mit der QF-Test component ID wieder in seinen ursprünglichen Zustand korrigieren. Wenn Sie den Originalwert nicht mehr wissen, können Sie ihn mit Hilfe von Bearbeiten→Rückgängig machen restaurieren, vorausgesetzt Sie haben keine weiteren Änderungen in der Testsuite vorgenommen. Mit der korrekt wiederhergestellten QF-Test ID drücken Sie den ”Wiedergabe fortsetzen” Knopf um dort weiter zu machen, wo der Testlauf unterbrochen wurde. Sie sehen, dass nun die Testsuite wie ursprünglich weiterläuft! 3.9 Sprung ins Protokoll Hin und wieder ist die Fehlersuche in Ihrer Testsuite nicht so einfach wie in unserem Beispiel. Die Ursachen für einige Probleme, die zu Exceptions führen, müssen auch nicht im aktuellen Knoten liegen sondern können evtl. aus einer weiter zurückliegenden Sequenz von Events stammen. Unter solchen Umständen kann das Protokoll äußerst hilfreich für Debugging Zwecke sein, da es im Detail die Schritte enthält, wie QF-Test jeden Knoten durchläuft und wie QF-Test IDs von Komponenten, Prozedurnamen, Variablen und andere Elemente 3.9. Sprung ins Protokoll 52 aufgelöst werden. Da die Suche im Protokoll mühsam sein kann, besonders wenn Ihre Testsuite komplexer wird, stellt der Debugger einen einfachen Mechanismus zur Verfügung, um direkt in den relevanten Bereich im Protokoll zu springen, wenn ein Fehler auftritt. (49) Wir werden dies am gleichen Beispiel wie in Abschnitt 3.8 demonstrieren, wo eine Exception aufgrund einer unbekannten QF-Test ID geworfen wurde. Wiederholen Sie bitte die Schritte des Kapitels und führen Sie die Testsuite aus, außer dass Sie den Fehler noch nicht beheben. Wir werden zuerst das Protokoll untersuchen. Um an die relevante Position im Protokoll zu springen wählen Sie im Menü Debugger→In Protokoll springen oder benutzen Sie das Strg-J Tastenkürzel. Das Protokoll wird nun geöffnet und der relevante Knoten wird automatisch selektiert, wie unten gezeigt: Abbildung 3.10: In das Protokoll springen. Nehmen Sie sich nun ein wenig Zeit, um die verschiedenen Elemente im Protokoll genauer zu untersuchen. Obwohl das verwendete Beispiel einfach ist, fördert es Ihr Verständnis für dieses wirksame Hilfsmittel. Dieses wird Ihnen später von großem Nutzen sein, wenn Ihre eigenen Testsuiten komplexer werden. Wenn Sie damit fertig sind, können Sie mit dem Beispiel wie im letzten Kapitel fortfahren oder auch einfach den Testlauf abbrechen. Achten Sie jedoch darauf die Testsuite nicht zu speichern, falls Sie den aktuellen Fehler nicht korrigiert haben. Kapitel 4 Schreiben einer Prozedur [30-45 Min] In diesem und den folgenden Kapiteln beginnen wir damit, einige fortgeschrittene Konzepte von QF-Test zu erkunden. Dies soll durch einen ”Hands-On” Ansatz geschehen, welcher Ihnen einen guten Überblick vermittelt. Wir werden u. a. das hilfreiche Konzept von Prozeduren in QF-Test erläutern. Auf diesem Weg werden Sie auch andere Einblicke gewinnen, die Ihnen beim Entwickeln eigener Testsuiten nützlich sein werden. Als ersten Schritt werden Sie eine einfache Prozedur erstellen, die ein Kontrollkästchen im SUT Client auswählt. 4.1 Los geht es mit einer neuen Testsuite An dieser Stelle im Tutorial sind Sie in der Lage Ihre eigene Testsuite zu erstellen, die Sie im weiteren Verlauf stetig ausbauen werden. Wählen Sie dazu den Menüeintrag Datei→Neue Suite... . Hinweis Wie Sie zweifellos bemerkt haben gibt es Tastaturkürzel für die meisten Menüoptionen. Sie sind ein schneller Weg hilfreiche Operationen durch einen einfachen Tastendruck auszuführen. Das Kommando Datei→Neue Suite... z.B. hat das Kürzel Strg-N . Sie sehen Kürzel direkt neben den meisten Optionen in den QF-Test Menüs, aber es gibt auch noch weitere, die nicht direkt aus der Benutzeroberfläche ersichtlich sind. Eine vollständige Übersicht finden Sie im Anhang Tastaturkürzel im Handbuch. Dort findet sich auch ein kleiner Helfer für die Funktionstastenbelegung von QF-Test zum Befestigen an der Tastatur. Natürlich braucht eine Testsuite einen SUT Client. Das Options Demo, mit dem Sie ja bereits aus den vorausgegangenen Kapiteln bestens vertraut sind, ist eine einfache Applikation, die sich ideal als SUT eignet. Unser nächster Schritt ist es, dieses Programm als SUT für unsere neue Testsuite einzurichten. 4.1. Los geht es mit einer neuen Testsuite 54 Dafür benötigen Sie einen Vorbereitungsknoten, in dem das Programm gestartet und eine Verbindung zwischen Applikation und QF-Test hergestellt wird. Diesen Schritt können Sie einfach dadurch erreichen, indem Sie den Vorbereitungsknoten von der Testsuite Options.qft in Ihre neue Suite kopieren. Öffnen Sie dazu Options.qft (schla(2) gen Sie in Kapitel 1 nach, wenn Sie hier nicht weiterkommen) und expandieren Sie den Knoten ”Testfallsatz: Options”. Der erste darin enthaltene Knoten ist die Vorbereitungssequenz ”Start the application”. Wählen Sie diesen Knoten aus und kopieren Sie ihn mit Bearbeiten→Kopieren in die Zwischenablage. Kehren Sie nun zu Ihrer eigenen Testsuite zurück und expandieren Sie dort den ”Test” Knoten, so dass ein Einfügen möglich ist. Dann können Sie mit Bearbeiten→Einfügen die Vorbereitungssequenz an ihren Zielort platzieren. Eine Aufräumsequenz ist üblicherweise dem Vorbereitungsknoten zugeordnet und macht Schritte der Vorbereitung rückgängig. In unserem Fall soll das Aufräumen gleichbedeutend mit dem Stoppen der Applikation sein. Sie können deshalb äquivalent ”Aufräumen: Stop the application” aus der Testsuite zu oben den Knoten Options.qft kopieren und in Ihre eigene Suite einfügen, natürlich nach dem Vorbereitungsknoten. Es gibt einen weiteren Schritt zu tun, bevor dieser Abschnitt abgeschlossen ist - das Kopieren der Fenster und Komponenten aus Options.qft in Ihre eigene Testsuite. Der Grund für diesen Schritt mag für Sie nicht sofort ersichtlich sein. Wir werden das Thema ”Komponenten” etwas später in diesem Kapitel ausführlich diskutieren. Im Moment soll die Erklärung genügen, dass Komponenteninformationen unter dem Knoten ”Fenster und Komponenten” einer Testsuite in einer Weise abgelegt werden, dass QF-Test damit Elemente wie Menüs oder Buttons im SUT erkennen kann. Expandieren Sie bitte nun den ”Fenster und Komponenten” Knoten in Options.qft und markieren Sie alle erscheinenden Kindknoten. Dann können Sie diese mit den Kopieren und Einfügen Methoden in den gleichen Knoten Ihrer Testsuite kopieren. Im folgenden Bild sehen Sie, wie Ihre Testsuite nun aussehen sollte. 4.1. Los geht es mit einer neuen Testsuite 55 Abbildung 4.1: Grundgerüst der neuen Testsuite An diesem Punkt angelangt haben Sie ein funktionierendes Grundgerüst für Ihre Testsuite erzeugt. Wir werden es in den folgenden Abschnitten mit verschiedenen Tests und Prozeduren beleben. Sie können nun das SUT starten, indem Sie den Vorbereitungsknoten auswählen und Wiedergabeknopf drücken. Wenn das SUT hochgelaufen ist und sein Fenster den erscheint, wechseln Sie zu diesem und selektieren Sie den Knoten ”Miscellaneous” im Baum für die Einstellungen auf der linken Seite. Auf der rechten Seite erscheinen verschiedene Optionen für das Demoprogramm, darunter auch ein Kontrollkästchen mit der Bezeichnung ”A BooleanOption”, wie im folgenden Bild dargestellt: 4.2. Erstellen einer Prozedur 56 Abbildung 4.2: Kontrollkästchen in den ”Miscellaneous” Optionen des SUT Dies ist das Kontrollkästchen, das Sie mit Ihrer neuen Prozedur im Rahmen der nächsten Abschnitte steuern werden. 4.2 Erstellen einer Prozedur Als Programmierkonstrukt ist eine Prozedur typischerweise als eine Methode definiert, um eine bestimmte, sich wiederholende Aufgabe zu erfüllen - z.B. ein Fenster zu öffnen oder zu überprüfen ob eine gewisse Taste gedrückt wurde. In diesem Teil des Tutorials werden Sie eine Prozedur erzeugen, die ein Kontrollkästchen im SUT aktiviert. 4.3. Hinzufügen eines Check Knotens Zuerst expandieren Sie bitte den 57 ”Prozeduren” Knoten in Ihrer neuen Testsuite. Hinweis QF-Test gibt Ihnen gute visuelle Hinweise ob ein Knoten geschlossen oder expandiert ist. Das Symbol des Knotens ”Prozeduren” z.B. ändert sich von (geschlossen) nach (expandiert). Nun wählen Sie den Knoten ”Prozeduren” aus und benutzen anschließend im Menü die Option Einfügen→Prozedur Knoten→Prozedur . Ein neues Dialogfenster erscheint, das die Eingabe des Prozedurnamens und weiterer Details erlaubt. Tragen Sie bitte ”selectCheckbox” als Namen ein und betätigen Sie mit dem ”OK” Button. Die resultierende Testsuite ist im nachfolgenden Bild gezeigt: Abbildung 4.3: Hinzufügen einer Prozedur Hinweis Eigenschaften eines Knotens in QF-Test (wie der Name einer Prozedur) können einfach geändert werden, indem man den Knoten auswählt und sie in der Detailansicht rechts editiert. Eine andere Möglichkeit ist die Option Eigenschaften... im Kontextmenü des Knotens, das über die rechte Maustaste erreicht werden kann. In jedem Fall müssen Sie Ihre Änderungen mit ”OK” bestätigen. 4.3 Hinzufügen eines Check Knotens Nun sind wir bereit, der Prozedur wirklichen Inhalt zu geben. Doch stellen Sie sich bitte zuerst selbst die Frage, wie Sie weitermachen würden, um das Kontrollkästchen zu setzen. Einer der ersten notwendigen Schritte ist, den Status des Kontrollkästchens zu überprüfen, bevor wir ihn dann setzen. Schließlich gibt es in dem Fall, dass das Kontrollkästchen bereits ausgewählt ist, nichts zu tun, als es so zu belassen wie es ist. Im anderen Fall (es ist nicht ausgewählt) machen wir weiter, indem wir es aktivieren. Solche Überprüfungen lassen sich in QF-Test mit ”Check” Knoten realisieren, die verschiedene Arten von Abfragen über den Zustand eines Elementes im SUT ermöglichen. Wir werden mit einem ”Check” Knoten vom Typ ”Check Boolean: selected” beginnen. Wie der Name sagt, überprüft dieser, ob sich eine Komponente im Zustand ”ausgewählt” befindet oder nicht. Sie habe hoffentlich bereits aus vorausgegangenen Kapiteln Erfahrung mit ”Check” Kno(34) ten. Wenn nicht, kann es hilfreich sein, einen Blick zurück in Abschnitt 2.5 zu werfen. 4.3. Hinzufügen eines Check Knotens 58 Um den ”Check Boolean: selected” Knoten einzufügen, werden Sie nun ähnliche Schritte ausführen. Gehen Sie zuerst in das Fenster des SUT und selektieren Sie dort die Option ”Miscellaneous” im ”Preferences” Baum auf der linken Seite, wie es auch schon in Abbildung (56) 4.2 gezeigt wurde. Das erlaubt Ihnen einen leichten Zugriff auf die gewünschte Komponente, wenn die Aufnahme erst einmal gestartet wurde. Kehren Sie nun in Ihre Testsuite zurück und drücken Sie den Knopf ”Check aufnehmen” und springen gleich wieder zum Fenster des SUT. Wenn Sie dort die Maus über verschiedene Komponenten bewegen sehen Sie, dass sich deren Farbe jeweils invertiert. Wählen Sie so das Kontrollkästchen ”A BooleanOption”, das wir schon vorher betrachtet hatten, aus. Das erscheinende Kontextmenü enthält neben der Auswahl von möglichen Checks, die wir schon in früheren Beispielen gesehen hatten, eine Option für ”Selektion”, wie die nachfolgende Grafik zeigt. 4.3. Hinzufügen eines Check Knotens 59 Abbildung 4.4: Aufnehmen des ”Check Boolean: selected” Knotens Wählen Sie den Punkt ”Selektion” aus und kehren Sie nun in Ihre Testsuite zurück, wo Sie die Aufnahme mit dem ”Stop” Knopf beenden. QF-Test platziert die aufgenommene Sequenz im Knoten ”Extrasequenzen”- sie wird direkt nach dem Stoppen der Aufnahme sichtbar. Wenn Sie diesen Knoten expandieren, sieht man darin unseren ”Check Boolean: selected” Knoten. Dieser muss nun von dort in Ihre Prozedur verschoben werden. Sie können entweder nur den Knoten selbst oder die gesamte Sequenz transferieren. Der Unterschied ist mehr ästhetischer Natur, da die Sequenz ja nur den einen Knoten enthält. Führen Sie den Vorgang mit der Kopieren oder Ausschneiden und der Einfügen Funktion aus. Vergessen Sie nicht, die ”selectCheckbox” Prozedur zu expandieren, be- 4.4. Über Komponenten 60 vor Sie den kopierten Knoten einfügen. Ansonsten wird er nicht an der richtigen Stelle platziert und Sie müssen nacharbeiten, damit Ihre Testsuite dem folgenden Bild entspricht. Abbildung 4.5: Prozedur mit ”Check Boolean: selected” Knoten Hinweis QF-Test bietet die Option, eine aufgenommene Sequenz direkt an der aktuellen Position einzufügen. Dies erspart das wiederholte Ausschneiden und Einfügen. Aktivieren Sie hierfür unter Bearbeiten→Optionen in der Kategorie ”Aufnahme” das Auswahlkästchen ”Aufnahme bei aktueller Selektion einfügen”. Und nun probieren Sie es aus! Markieren Sie Ihre Prozedur und drücken Sie den Wiedergabe Knopf. An dieser Stelle passiert nicht viel aber in der Statusleiste zeigt QF-Test an, dass die Prozedur fehlerfrei beendet wurde. Der erste Schritt ist getan. 4.4 Über Komponenten Bevor wir fortfahren, könnte ein wenig Hintergrundinformation zu Checks und Komponenten hilfreich sein, die aus dem bisherigen Inhalt des Tutorials noch nicht unmittelbar hervorging. Eine Komponente ist einfach ein Element des SUT, wie ein Button, ein Menü oder (wie in unserem Fall) ein Kontrollkästchen. Jede Komponente sollte innerhalb der Testsuite eine eindeutige QF-Test ID besitzen, so dass QF-Test die Komponente beim Ausführen findet. Wählen Sie nun den Knoten ”Check Boolean: selected” aus, den Sie im vorhergehenden Kapitel aufgenommen hatten. Unter seinen Eigenschaften, die in der Detailansicht zu sehen sind, befindet sich auch ein Feld QF-Test ID. Dessen Inhalt sollte die QF-Test ID (56) des Kontrollkästchens enthalten, welches wir in Abbildung 4.2 identifiziert haben. Die QF-Test ID sollte ”CheckBox-boolean2” lauten. Die QF-Test ID, die Sie dort sehen, ist ein Name, ein praktischer Weg für Sie und QFTest, Komponenten zu identifizieren und zu referenzieren. QF-Test IDs werden in Ihrer Testsuite unter dem Knoten ”Fenster und Komponenten” angelegt, wann immer eine Komponente des SUT aufgenommen wird. Wenn Sie alle Knoten unterhalb dieses Bereiches, wie vom folgenden Bild dargestellt, expandieren, sollten Sie dort auch unser Kontrollkästchen finden. 4.5. Der Try/Catch Mechanismus 61 Abbildung 4.6: Die Kontrollkästchen Komponente im Komponentenbaum Hinweis Es gibt einen komfortablen Weg in QF-Test, um Komponenten zu finden. Öffnen Sie hierfür das Kontextmenü des Knotens ”Check Boolean: selected” mit der rechten Maustaste und wählen Sie ”Komponente finden” (oder auch einfach Strg-W ). Dies bringt Sie geradewegs zum Knoten der Komponente im Bereich ”Fenster und Komponenten”. Mit der Tastenkombination Strg-Backspace kann man von dort wieder zurück zum ”Check” Knoten springen. Klicken Sie nun auf den Knoten der ”CheckBox-boolean2” Komponente. Rechts können Sie dann ein wenig sehen, wie QF-Test Komponenten intern identifiziert. Komponentenerkennung in QF-Test ist ein komplexes Thema und wir werden im Rahmen diese Tutorials nicht tiefer einsteigen. Für weitere Details über Komponenten sei auf das Kapitel im Handbuch verwiesen. 4.5 Der Try/Catch Mechanismus Und was passiert, wenn unser Kontrollkästchen nicht gesetzt ist? Klicken Sie auf das Kontrollkästchen, um es zu deaktivieren und lassen Sie die Prozedur nochmal laufen. Nun sollten Sie folgende Meldung erhalten: Abbildung 4.7: ”Check Boolean: selected” Fehler 4.5. Der Try/Catch Mechanismus 62 Die Fehlermeldung erscheint, weil Ihr Knoten ”Check Boolean: selected” das Kontrollkästchen im Zustand ”selektiert” erwartet. Klicken Sie nun auf den Knoten ”Check Boolean: selected”, so dass die Eigenschaften in der Detailansicht erscheinen. Darin sehen Sie ein Feld mit dem Titel ”Fehlerstufe der Meldung” und ein Kontrollkästchen ”Im Fehlerfall Exception werfen”. Mit diesen Eigenschaften können Sie die Aktion bestimmen, die QF-Test ausführt, wenn ein Check schief geht. Spielen Sie ein wenig mit diesen Einstellungen und beobachten Sie jeweils die Resultate nach dem Abspielen der Prozedur. Letztendlich wollen wir eine Exception werfen, wenn der Check fehlschlägt. Dies eröffnet die Möglichkeit, den sehr hilfreichen Try/Catch Mechanismus einzuführen. Setzen Sie also bitte die Option ”Im Fehlerfall Exception werfen” in den Eigenschaften, wie im nachfolgenden Bild gezeigt: Abbildung 4.8: Im Fehlerfall Exception werfen Der Try/Catch Mechanismus ist eine in vielen Programmiersprachen benutzte Technik zur Behandlung von Ausnahmesituationen (Exception handling). Das Konzept ist einfach: Mit ”Try” wird versucht eine Aktion durchzuführen. Wenn dabei eine Ausnahme auftritt, wird sie vom ”Catch” gefangen und es kann eine entsprechende Behandlung erfolgen. Keine Angst, wenn Sie mit diesem Konstrukt nicht vertraut sind - seine Funktionsweise wird sehr schnell klar, wenn man es in Aktion sieht. Fügen Sie nun bitte einen ”Try” Knoten ganz an den Anfang Ihrer Prozedur ein. Der Einfügepunkt ist immer nach dem gerade ausgewählten Knoten (Einfügemarke beachten). Anschließend wählen Sie im Menü Einfügen→Ablaufsteuerung→Try . Ein Dialog erscheint, um Ihnen die Eingabe der Knoteneigenschaften zu ermöglichen. Bei diesem Knoten sind keine Eingaben notwendig, für eine bessere Lesbarkeit kann jedoch das Namensfeld hilfreich sein. Wir füllten es mit ”checkbox selected”. Expandieren Sie den ”Try” Knoten, so dass darunter neue Knoten eingefügt werden können. Es werden alle Aktionen überwacht, die innerhalb dieses ”Try” Blocks ausgeführt werden, und ein ”Catch” Knoten kann (wie in Kürze beschrieben) entsprechend die Exception abfangen. Doch zuerst wollen wir den Knoten ”Check Boolean: selected”, der unsere Aktion darstellt, in den ”Try” Block einfügen. Der Knoten sollte sich noch in Ihrer Prozedur befinden, ist aber nicht an der richtigen Position. Benutzen Sie bitte die Ausschneiden und Einfügen Funktionen, um den ”Check” Knoten direkt unterhalb des ”Try” Knotens einzufügen. Ein ”Try” Knoten ohne einen ”Catch” Knoten ist nutzlos. Fügen Sie deshalb einen 4.5. Der Try/Catch Mechanismus 63 ”Catch” Knoten mit Einfügen→Ablaufsteuerung→Catch direkt nach Ihrem ”Check” Knoten (und immernoch innerhalb des ”Try” Blocks”) ein. Analog zu vorher erscheint ein Eingabedialog. Für den ”Catch” Knoten müssen Sie festlegen, welcher Typ von Exception durch ihn gefangen werden soll. Das erste Feld im Dialog trägt die Beschriftung ”Exception Klasse”, das eine Liste von allen möglichen Exceptions enthält. Wählen Sie hier bitte die CheckFailedException. Abbildung 4.9: Auswählen der Exception für den ”Catch” Knoten Der Try/Catch Mechanismus wird als deterministisches Konstrukt bezeichnet. Das bedeutet, dass die Exception (oder Exceptions), die gefangen werden, sich direkt auf die im ”Try” Block ausgeführten Aktionen beziehen. In unserem Fall enthält der ”Try” Block einen ”Check” Knoten, so dass die zu fangende Exception eine ”CheckFailedException” ist. Die zu fangende Exception muss aber natürlich beim Implementieren eines Try/Catch Blockes nicht immer unmittelbar offensichtlich sein. Falls Sie sich nicht sicher sind, welche Exception gefangen werden muss, hilft das Protokoll weiter. Versuchen Sie nun erneut, Ihre Prozedur laufen zu lassen. Keine Angst, auch wenn die Try/Catch Knoten nicht vollständig sind. Wichtig ist, dass der ”Check Boolean: selected” Knoten immer noch vorhanden ist und sein Attribut ”Im Fehlerfall Exception werfen” gesetzt ist. Danach öffnen Sie das letzte Protokoll im Menü Wiedergabe (das neueste ist immer an oberster Position) und suchen den Knoten, in dem die Exception geworfen wird, wie im folgenden Bild dargestellt: Abbildung 4.10: CheckFailedException im Protokoll Hinweis Mehr Informationen zum Thema Exceptions und eine vollständige List aller Typen finden Sie im Referenzteil des Handbuchs. An dieser Stelle sollte Ihre Prozedur nun folgendermaßen aussehen: 4.6. Fertigstellen der Auswahllogik 64 Abbildung 4.11: Prozedur mit Try/Catch Konstrukt Hinweis Lassen Sie QF-Test Ihnen helfen, wenn Sie Fragen zu einem bestimmten Knotentyp haben: Klicken Sie dazu einfach mit der rechten Maustaste auf den gewünschten Knoten und wählen Sie den Punkt ”Was ist das?” aus dem erscheinenden Kontextmenü. QF-Test führt Sie dann an die richtige Stelle im Handbuch. 4.6 Fertigstellen der Auswahllogik Ihre Try/Catch Knoten sind nun an Ort und Stelle - der letzte verbleibende Schritt ist das Fertigstellen der Aktionen, die ausgeführt werden sollen, wenn die ”CheckFailedException” geworfen und gefangen wird. Als Erinnerung: Die Exception wird geworfen, wenn der Check fehlschlägt, z.B. wenn das Kontrollkästchen nicht gesetzt ist. Die Aktion, die wir benötigen, wenn die Exception gefangen wird, ist die Aktivierung des Kontrollkästchens. Hierfür müssen wir eine neue Sequenz vom SUT aufnehmen. Klicken Sie auf den Aufnahmeknopf und wechseln Sie zum Fenster des SUT. Das Einzige was wir aufnehmen wollen, ist ein Mausklick auf das ”A BooleanOption” Kontrollkästchen. Klicken Sie also bitte auf das Kontrollkästchen, so dass sich dessen Status von ”aktiv” auf ”inaktiv” oder umgekehrt ändert. Ob so oder so spielt keine Rolle, da wir nur eine Zustandsänderung erreichen wollen. Nun kehren wir zur Testsuite zurück und betätigen den Knopf ”Aufnahme beenden”. Nachdem die Aufnahme beendet ist, platziert QF-Test die aufgenommene Sequenz in Bereich ”Extrasequenzen”. Darin sollten Sie einen ”Mausklick” Knoten finden. Wenn Sie einen Blick auf die Knotenattribute werfen, sehen Sie verschiedene vertraute Felder wie die Komponenten ID des Kontrollkästchens. Hinweis Es ist in der Regel nicht nötig, dass Sie Änderungen an den Eigenschaften von diesem Knotens vornehmen, höchstens ein Eintrag in das Feld ”Bemerkung” kann sinnvoll sein. Bemerkungen haben keinen Einfluss auf den Test, sondern verbessern lediglich die Lesbarkeit der Testsuite. Wie wir es bereits früher bei aufgenommenen Knoten getan haben, müssen wir den ”Mausklick” Knoten von den ”Extrasequenzen” in unsere Prozedur mit den Ausschneiden / Kopieren und Einfügen Funktionen transportieren. Expandieren Sie den ”Catch” Knoten in Ihrer Prozedur und fügen Sie den neuen Knoten direkt darunter ein. Ihre Prozedur sollte nun folgendermaßen aussehen: 4.7. Verbessern der Prozedur 65 Abbildung 4.12: Prozedur mit komplettiertem Try/Catch Mechanismus Ihre Prozedur ist nun eine vollständige funktionale Einheit. Klicken Sie auf die Prozedur Wiedergabe Button aus. Je nach Staund führen Sie diese einige Male mit dem tus der Checkbox im SUT werden beide logischen Pfade in der Prozedur ausgeführt. (40) Die Funktion ”Einzelschritt ausführen” des Debuggers (siehe Kapitel 3 ) ist ein ausgezeichnetes Hilfsmittel, um genau nachzuvollziehen, wie der Try/Catch Mechanismus funktioniert. An dieser Stelle noch ein kleiner Hinweis. Eine Bibliothek mit Hilfsprozeduren, wie ”se(86) lectCheckbox”, ist bei QF-Test bereits enthalten. Diese wird ausführlich in Kapitel 7 beschrieben. Wir wollen uns jedoch zuerst noch der Verallgemeinerung unserer Prozedur widmen. 4.7 Verbessern der Prozedur Wir werden nun noch eine letzte Verbesserung an unserer Prozedur durchführen, bevor wir dieses Kapitel des Tutorials beenden. Das Problem dieser Prozedur ist, dass sie nur für genau dieses spezifische Kontrollkästchen funktioniert. Was ist, wenn im SUT mehrere solche Komponenten zu manipulieren sind. Sollen wir je eine Prozedur für jedes individuelle Kontrollkästchen schreiben? Die Lösung kommt zu uns in Form von Variablen. Eine Variable kann benutzt werden, um die QF-Test ID der Komponente zu ersetzen, so dass die Prozedur für jedes Kontrollkästchen im SUT verwendet werden kann. Die Variablensyntax in QF-Test ist wie in allen Computerprogrammen spezifisch. Eine Variable wird einfach durch einen Namen definiert. Wenn jedoch auf die Variable zugegriffen werden soll, so ist die notwendige Syntax $(Name). Wir werden in den folgenden Abschnitten mehr darüber lernen. Wir wollen nun in der Prozedur statt des spezifischen Kontrollkästchens eine Variable referenzieren. Wir nennen die Variable zum Beispiel id. Für diese Aktion öffnen Sie einfach die Detailansichten der Knoten ”Check Boolean: selected” und ”Mausklick”. Ersetzen Sie dort jeweils im Feld QF-Test component ID den Ausdruck CheckBox-boolean2 durch die Variable $(id). Die Prozedur sollte nun wie folgt aussehen. 4.8. Aufrufen der Prozedur 66 Abbildung 4.13: Variable anstelle einer festen Komponente 4.8 Aufrufen der Prozedur Wenn Sie versuchen die Prozedur nun laufen zu lassen, werden Sie einen Fehler erhalten ”Unbekannte Variable”. Mit einem zugehörigen Erklärungstext teilt Ihnen QF-Test so mit, dass kein Wert für die Variable gesetzt ist. Und wie setzt man die Variable? In unserem Beispiel benutzen wir den gebräuchlichsten Fall, die Prozedur einfach mit einem spezifischen Wert für die Variable aufzurufen. Man nennt dies in der Fachsprache ”ein Argument (oder einen Parameter) an eine Prozedur übergeben”. Wir wollen nun den Aufruf der Prozedur einbauen. Dazu kehren wir zum Wurzel-Testknoten der Testsuite zurück. Schließen Sie den Knoten ”Vorbereitung”, so dass Sie danach einen Knoten einfügen können. Zuerst benötigen wir einen ”Testfall” mittels Einfügen→Test und Sequenz Knoten→Testfall , dem Sie einen beliebigen Namen geben können. Nach dem Aufklappen das ”Testfall” Knotens erzeugen wir den Prozeduraufruf entweder mittels Einfügen→Prozedur Knoten→Prozeduraufruf oder durch Drücken von Strg-A . Es erscheint ein Dialog, der es Ihnen ermöglicht, die Knotenattribute zu bearbeiten. Hier ist es zwingend notwendig, einige Werte anzugeben. Als erstes geben Sie den Namen der gewünschten Prozedur ein, in unserem Fall ”selectCheckbox”. Hinweis Der dritte und vielleicht einfachste Weg ist Drag&Drop. Wenn Sie den ”selectCheckbox” Prozedurknoten mit der Maus aus dem Bereich ”Prozeduren” nach oben in den ”Testfall” ziehen, wird dieser automatisch einen ”Prozeduraufruf” umgewandelt (da ”Prozedur” Knoten dort nicht erlaubtsind). Den gleichen Effekt erhält man, wenn man den Prozedurknoten z.B. Strg-C kopiert und dann im ”Testfall” Knoten Strg-V zum Einfügen drückt. Als Nächstes wollen wir die Variable hinzufügen, die als Argument an die Prozedur übergeben wird. Dies lässt sich über die Tabelle ”Variablen” erreichen, die das nächste Element im Fenster mit den Knoteneigenschaften ist. Erzeugen Sie dort eine neue Zeile, indem Sie auf das Icon ganz links klicken. Ein neuer Dialog erscheint für die Definition der neuen Variable. In diesem Fenster tragen Sie id als Namen ein und CheckBox-boolean2 als Wert ein. Der Dialog mit den Eigenschaften des Prozedu- 4.8. Aufrufen der Prozedur 67 raufrufs sollte somit folgendermaßen ausgefüllt sein: Abbildung 4.14: Eigenschaften des Prozeduraufrufs Hinweis Außer den Icons, die für die Funktionen zum Hinzufügen, Bearbeiten, Entfernen von Elementen in der Variablentabelle stehen, gibt es ein weiteres Symbol in der obigen Grafik: der kleine gelb-rote Button rechts neben dem Feld ”Prozedurname”. Dieses Icon dient dazu, einen sehr hilfreichen Dialog zu öffnen, mit dem sich Prozeduren direkt aus einer Liste auswählen lassen. Die Liste enthält alle Prozeduren der Testsuite (und sogar auch die anderer geöffneter Testsuiten). Für unseren Fall finden Sie bitte die ”selectCheckbox” Prozedur und bestätigen Sie mit ”OK”. QF-Test überträgt damit automatisch den entsprechenden Namen in das zugehörige Feld im Eigenschaftenfenster. Damit sind die Attribute des Knotens ”Prozeduraufruf” komplett und Sie können ihn mit ”OK” schließen. Anschließend klicken Sie auf den neuen Knoten und starten ihn mit Wiedergabeknopf. Sie werden sehen, dass beim Aufruf nun die QF-Test ID des dem Kontrollkästchens an die Prozedur übergeben wird, so dass ”selectCheckbox” sauber arbeiten kann. Wenn das SUT mehrere Kontrollkästchen beinhalten würde, könnten Sie nun verschiedene Prozeduraufrufe realisieren, jeden mit der entsprechenden QF-Test ID der Komponente als Argument! Falls Sie die gesamte Testsuite nun durchlaufen lassen wollen, werden Sie eine Fehlermeldung erhalten, die darauf hinweist, dass die Zielkomponente Checkbox-boolean2 nicht gefunden wurde. Dieses Problem wird in Kapitel 7.3 behandelt, daher könnten Sie 4.8. Aufrufen der Prozedur 68 diese Passage auch überspringen. Wir empfehlen aber, es zu Übungs- und Verständniszwecken hier anzugehen. Ein Blick in das Protokoll (im Wiedergabe-Menü) zeigt, ”wo der Wurm drin ist”. Besonders das enthaltene Bildschirmabbild ist hierbei hilfreich. Wie Sie feststellen, befindet sich die Zielkomponente nicht auf der Startseite des Option Demos. Zunächst brauchen wir daher eine Sequenz, die den ”Miscellaneous” Knoten expandiert. Eine solche sollten Sie inzwischen mit Leichtigkeit aufnehmen können (das SUT öffnen, auf den ”Aufnahme starten” Knopf, dann den ”Miscellaneous” Knoten und ”Aufnahme beenden” drücken). Wo fügen wir diese Sequenz nun in unsere Testsuite ein? Intuitiv ist man versucht, sie über den Prozeduraufrufen zu platzieren, aber das führt zu derselben Fehlermeldung. Ein Blick ins Protokoll offenbart auch hier den Grund - weil jede Sequenz zwischen ”Vorbereitung: Start the application” und ”Aufräumen: Stop the application” einen Start UND Stopp des SUT zur Folge hat. Um also den gewünschten Zustand des SUTs für alles Testfälle zu gewährleisten, müssten Sie diese Sequenz in die Vorbereitung einbinden. Für den Fall, dass nur eine Prozedur an dieser bestimmten Stelle beginnen soll, fügen Sie eine neue Sequenz ein, die den aufgenommenen Mausklick und den Prozeduraufruf enthält. Kapitel 5 Erstellen einer verallgemeinerten Prozedur [30-45 Min] In diesem Kapitel zeigen wir Ihnen, wie Sie die Prozedur, die Sie im letzten Kapitel erstellt haben, verallgemeinern können, um sie noch nützlicher zu machen. Nach der Einführung von Packages sind Sie dann in der Lage, Ihre eigene Bibliothek mit allgemeinen Hilfsfunktionen zu schreiben. 5.1 Anlegen eines ”Package” Knotens Wenn Sie im Testalltag weitere Prozeduren erstellen, werden Sie schnell feststellen, dass die Dinge zunehmend unordentlich und unübersichtlich werden - ähnlich einem Schreibtisch, auf dem wichtige Dokumente kreuz und quer verstreut sind. Wie ein Ordner, der Ihnen hilft, Dokumente zu organisieren und in verschiedene Kategorien einzuteilen, dienen Packages in QF-Test dazu, Prozeduren in Gruppen zusammenzufassen. Packages können dabei sowohl Prozeduren als auch weitere Packages enthalten. Sie können Ihre Packages und Prozeduren anordnen, wie immer es Ihnen beliebt, aber es ist sicherlich sinnvoll, Prozeduren mit gemeinsamer Funktionalität in ein gemeinsames Package zu packen. Im vorhergehenden Kapitel haben Sie eine Prozedur namens ”selectCheckbox” geschrieben, die es ermöglicht, ein Kontrollkästchen im SUT zu aktivieren. Analog könnten wir uns weitere Prozeduren vorstellen, die sich mit Kontrollkästchen befassen, zum Beispiel zum Deaktivieren oder zum Auslesen oder Überprüfen des aktuellen Zustands. Es gibt viele Möglichkeiten, die alle in eine gemeinsame Kategorie fallen, eben Hilfsfunktionen für Kontrollkästchen. Lassen Sie uns also ein Package für diese Prozeduren erstellen. Selektieren Sie den Knoten ”Prozeduren” in Ihrer Testsuite, klappen Sie ihn aus und 5.2. Verschieben der Prozedur 70 wählen Sie den Menüeintrag Einfügen→Prozedur Knoten→Package . Dadurch öffnet sich ein Dialog für die Eigenschaften des neuen Packages, in dem Sie lediglich den Namen angeben müssen. Nennen Sie das neue Package ”checkbox”. 5.2 Verschieben der Prozedur Sie haben bereits eine Prozedur, die sich auf Kontrollkästchen bezieht und die Sie nun in Ihr neues Package verschieben können. Verwenden Sie dazu direkt die Maus oder auch die Funktionen Ausschneiden und Einfügen . Ein Dialog wird erscheinen, der nachfragt ob alle Referenzen auf diese Prozedur automatisch angepasst werden sollen. Wählen Sie bitte ”Ja” und lassen Sie ”Angepasste Referenzen nach Aktion anzeigen” aktiviert, dann erscheint nach der Aktion eine Liste mit betroffenen Knoten. In unserem Fall ist es nur ein Prozeduraufruf. Nun, da sich die Prozedur im Package ”checkbox” befindet, ist der Name ”selectCheckbox” ein wenig redundant. Lassen Sie uns den Namen der Prozedur zu ”select” abändern. Dies ist ein weiterer kleiner Vorteil der Organisation in Packages: Befindet sich eine Prozedur im Package ”checkbox”, kann man automatisch davon ausgehen, dass sie sich auf Kontrollkästchen bezieht. Erneut werden Sie gefragt ob Referenzen automatisch angepasst werden sollen, was natürlich hilfreich ist. Ihre Testsuite sollte jetzt wie folgt aussehen: Abbildung 5.1: Das ”checkbox” Package 5.3 Erstellen der ”deselect” Prozedur Unser nächster Schritt besteht darin, das Package zu erweitern, indem wir eine weitere Prozedur hinzufügen. Dazu bietet sich natürlich eine ”deselect” Prozedur an, die das Kontrollkästchen deaktiviert. Ihre neue ”deselect” Prozedur wird im Wesentlichen genauso funktionieren wie ”select”, mit einigen kleinen Änderungen in der Logik. Beginnen Sie damit, dass Sie eine Kopie 5.3. Erstellen der ”deselect” Prozedur 71 der Prozedur ”select” erstellen und diese ebenfalls in das ”checkbox” Package einfügen. Es stört nicht weiter, dass Sie damit zwei Prozeduren mit dem gleichen Namen im selben Package haben, das werden Sie als Nächstes ändern. Selektieren Sie eine der beiden ”select” Prozeduren und ändern Sie in der Detailansicht deren Namen zu ”deselect”. Im letzten Schritt dieses Abschnitts müssen wir nun die Logik so anpassen, dass die ”deselect” Prozedur das Kontrollkästchen auf den Zustand ”nicht selektiert” überprüft, bevor sie einen Event auslöst. Um das zu erreichen, müssen Sie lediglich eine einzige Änderung vornehmen: Expandieren Sie den ”Prozedur” Knoten so weit, bis Sie den Knoten ”Check Boolean: selected” finden. Sie werden sich erinnern, dass dies der Knoten ist, der den Zustand des Kontrollkästchens überprüft. In der ”select” Prozedur hatten wir es so eingerichtet, dass der Knoten eine Exception auslöst, wenn das Kontrollkästchen nicht selektiert ist. Um dies umzukehren, deaktivieren Sie einfach das Attribut ”Erwarteter Status” in der Detailansicht des ”Check” Knotens: Abbildung 5.2: Check für den Zustand ”nicht selektiert” Jetzt erwartet der Check für das Kontrollkästchen den Zustand ”nicht selektiert” und wirft eine Exception, wenn das Kästchen selektiert ist. Das war’s auch schon, zumindest was die Logik betrifft. Sie können noch die Namen und Kommentare innerhalb der Prozedur an die neuen Gegebenheiten anpassen, z.B. den Namen des ”Try” Knotens von ”checkbox selected” auf ”checkbox deselected” ändern. Ihr neues Package sollte nun in etwa so aussehen: 5.4. Aufruf der Prozedur 72 Abbildung 5.3: Das ”checkbox” Package mit zwei Prozeduren 5.4 Aufruf der Prozedur Im vorigen Kapitel hatten Sie einen Aufruf der Prozedur ”selectCheckbox” erstellt. Sie müssen nun diesen Prozeduraufruf so ändern, dass er den korrekten Namen erhält. Aufrufe von Prozeduren in Packages folgen einer einfachen Syntax, welche die gesamte Hierarchie einer Prozedur elegant widerspiegelt, nämlich in der Form Package.Prozedur. Ihr Prozeduraufruf erhält also den Namen ”checkbox.select” Hinweis Wie erwähnt können Packages nicht nur Prozeduren, sondern auch weitere Packages enthalten. Befindet sich eine Prozedur in solch einem verschachtelten Package, wird der Name nach der gleichen Regel wie oben gebildet, mit entsprechend vielen Package. Ausdrücken vorangesetzt. So könnte ein Prozeduraufruf etwa den Namen menu.file.open erhalten, was den zwei Packages ”menu” (das äußere) und ”file” (das innere) entspricht, mit der Prozedur namens ”open” im Package ”file”. Erstellen Sie einen weiteren Prozeduraufruf, diesmal für die Prozedur ”checkbox.deselect”. Sie sollten das mit Ihrer Erfahrung aus den bisherigen Kapiteln problemlos bewerkstelligen können. 5.5 Erstellen einer allgemeinen Prozedur Die zwei Prozeduren in Ihrem ”checkbox” Package erlauben Ihnen nun, entweder ein Kontrollkästchen zu aktivieren oder es zu deaktivieren. Wie wäre es, wenn wir jetzt eine Prozedur erstellen, die beide Möglichkeiten in sich vereint? In diesem und den folgenden Abschnitten werden wir eine Prozedur namens ”setState” erstellen, die den Status des Kontrollkästchens wahlweise auf ”selektiert” oder ”nicht selektiert” setzt. Zu diesem Zweck werden wir der Prozedur beim Aufruf einen Parameter namens ”select” übergeben. Hat dieser den Wert ”true”, wird die Prozedur das Kontrollkästchen aktivieren, 5.6. Angeben eines Defaultwerts 73 andernfalls deaktivieren. Beginnen wir damit die Prozedur ”setState” im Package ”checkbox” neu zu erstellen. (56) Wenn Sie dazu Hilfe benötigen, können Sie in Abschnitt 4.2 nachschlagen. 5.6 Angeben eines Defaultwerts Wie gerade erwähnt, wird unsere neue Prozedur eine Variable namens ”select” erhalten, die darüber entscheidet, was mit dem Kontrollkästchen zu geschehen hat. Ebenso wie die QF-Test ID der Komponente muss der Wert der Variable ”select” (entweder ”true” oder ”false”) beim Prozeduraufruf von ”setState” angegeben werden. Oft ist es sinnvoll, für den Wert einer Variable einer Prozedur einen Standardwert vorzugeben, der verwendet wird, wenn kein Wert beim Prozeduraufruf angegeben wird. Die Angabe eines Arguments beim Aufruf wird dadurch optional. Selektieren Sie die Prozedur ”setState” und werfen Sie einen Blick auf deren Attribute in der Detailansicht. Dort befindet sich auch ein Bereich zur Definition von Variablen. (66) Diese werden genauso bearbeitet, wie Sie es bereits in Abschnitt 4.8 getan haben. Fügen Sie jetzt auf die selbe Weise eine Variable namens ”select” hinzu und geben Sie ihr den Wert ”true”. Die Detailansicht sollte nun wie folgt aussehen: Abbildung 5.4: Standardwert für eine Variable der Prozedur 5.7. Das If/Else Konstrukt 74 Damit haben Sie QF-Test mitgeteilt, dass es den Wert ”true” für die Variable ”select” in der Prozedur ”setState” annehmen soll, wenn beim Aufruf der Prozedur kein Wert angegeben war. Ist dagegen ein Wert im Prozeduraufruf angegeben, wird der Defaultwert ignoriert. Hinweis Wenn Sie mit dem Konzept von Variablen vertraut sind, werden Sie hierin das Prinzip des Gültigkeitsbereichs einer Variablen erkennen. In diesem Stadium spielt es noch keine so große Rolle, aber wenn Sie sich öfter mit Variablen in QF-Test auseinandersetzen, sollten Sie unbedingt das Kapitel Variablen im Handbuch lesen. 5.7 Das If/Else Konstrukt Die Variable ”select” soll also darüber entscheiden, ob das Kontrollkästchen ein- oder ausgeschaltet werden soll. Um diese Logik in der Testsuite umzusetzen, benötigen wir die Knoten ”If” und ”Else”. Dieses Konstrukt ist sehr einfach einzusetzen. Der ”If” Knoten hat ein Attribut namens ”Bedingung”, welches bei seiner Ausführung ausgewertet wird. Liefert die Bedingung einen wahren Wert, werden die Knoten innerhalb des ”If” Knotens ausgeführt, andernfalls die Knoten des ”Else” Knotens. Selektieren und expandieren Sie nun die Prozedur ”setState” und fügen Sie mittels Einfügen→Ablaufsteuerung→If einen neuen ”If” Knoten ein. Wie üblich erscheint an dieser Stelle der Dialog mit den Attributen des Knotens. Für den ”If” Knoten müssen Sie die Bedingung angeben, um die Variable ”select” auszuwerten. Füllen Sie dieses Feld exakt wie folgt: Abbildung 5.5: Bedingung für den ”If” Knoten Erinnern Sie sich, dass zur Expansion einer Variablen in QF-Test die Syntax $(variable) dient. Die im Bild sichtbaren Anführungsstriche werden benötigt, da sich QF-Test zum Auswerten von Bedingungen der eingebauten Skriptsprache Jython bedient und dieser explizit mitgeteilt werden muss, dass es sich bei diesen Werten um Zeichenketten handelt. Zahlen und mathematische Ausdrücke werden ohne Anführungsstriche angegeben. Details hierzu finden Sie im Handbuch in den Abschnitten Variablen und Der ”If” Knoten. Wie bereits erwähnt, werden die Knoten innerhalb des ”If” Knotens ausgeführt, wenn dessen Bedingung einen wahren Wert liefert. Wir können also nun diese Logik entspre- 5.7. Das If/Else Konstrukt 75 chend ergänzen. Dazu gibt es verschiedene Möglichkeiten. Sie könnten zum Beispiel die Knoten aus der ”select” Prozedur hierher kopieren. Wie werden aber den einfachsten Weg gehen und einfach einen Prozeduraufruf zur Prozedur ”checkbox.select” an dieser Stelle einfügen. Achten Sie dabei darauf, dass der Prozeduraufruf innerhalb des (66) ”If” Knotens landet. Weitere Hilfe finden Sie in Abschnitt 4.8 . Kommen wir jetzt zum ”Else” Teil des Konstrukts. Nach dem letzten Knoten innerhalb des ”If” Knotens (in diesem Fall ist es nur einer, aber es könnten genausogut mehrere sein) können Sie mittels Einfügen→Ablaufsteuerung→Else einen ”Else” Knoten einfügen. Sie müssen keine weiteren Informationen in den Dialog für den ”Else” Knoten eingeben. Er stellt automatisch die logische Antithese zum entsprechenden ”If” Knoten dar. Schließlich vollenden wir das Konstrukt, indem wir die Knoten zum ”Else” Knoten hinzufügen, die dann ausgeführt werden sollen, wenn die Bedingung des ”If” Knotens nicht erfüllt ist. In unserem Beispiel ist das einfach ein Prozeduraufruf für ”checkbox.deselect”. Damit ist die Prozedur ”setState” komplett! Sie sollte in etwa so aussehen: Abbildung 5.6: Das If/Else Konstrukt Hinweis In unserem Beispiel führt die boolesche Natur der Variablen ”select” (nur die Werte ”wahr” und ”nicht wahr”) automatisch zu einem einfachen If/Else Konstrukt. Andere Beispiele mit mehreren Bedingungen wie zum Beispiel die Farben einer Ampel, können mit Hilfe des Konstrukts If/Elseif/Else gelöst werden. Das Konzept ist das gleiche, nur dass dabei mehrere Bedingungen ausgewertet werden. Ihre Logik könnte in etwa so aussehen: Abbildung 5.7: Das If/Elseif/Else Konstrukt Der ”Else” Knoten ist übrigens sowohl bei If/Else, als auch bei If/Elseif/Else optional. 5.8. 5.8 Aufruf der allgemeinen Prozedur 76 Aufruf der allgemeinen Prozedur Nun können Sie versuchen, Ihre neue ”setState” Prozedur aufzurufen. Erstellen Sie (66) hierzu analog zu Abschnitt 4.8 einen Prozeduraufruf Knoten. Sie benötigen natürlich immer noch einen QF-Test ID Wert für das ”id” Argument. Zusätzlich können Sie jetzt (optional) den Wert für die Variable ”select” angeben, zum Beispiel: Abbildung 5.8: Prozeduraufruf für ”setState” Anmerkung: Falls Sie eine Prozedur mit einem Rückgabewert erstellen möchten, z.B. eine getState Prozedur, können Sie für diesen Zweck einen Return Knoten innerhalb der Prozedur verwenden. Der zurückgegebene Wert kann dann an eine lokale oder globale Variable außerhalb der Prozedur zugewiesen werden. Dies geschieht mit Hilfe des Attributs ”Variable für Rückgabewert” des Knotens ”Prozeduraufruf”, das im obigen Bild gezeigt wird. Weitere Informationen finden Sie im Referenzhandbuch. 5.9 Dokumentieren der Prozedur Nachdem Sie die Implementierung Ihrer Prozedur erfolgreich abgeschlossen haben, möchten wir Ihnen nun einen bequemen Weg zeigen, um eine Dokumentation dafür zu erzeugen. Für die Programmiersprache Java gibt es eine standardisierte Methode um Quellcode zu dokumentieren - sie heißt javadoc. Dabei werden spezielle Schlüsselworte (Tags) in Kommentaren in den Quellcode eingefügt, die vom javadoc Tool ausgewertet und in Form eines wohlstrukturierten HTML Dokuments aufbereitet werden. QF-Test bietet einen äquivalenten Mechanismus an, um Packages und Prozeduren zu dokumentieren. Wir werden Ihnen im Folgenden zeigen, wie es funktioniert. Unter qfs_pkgdoc.html können Sie vorab einen Blick auf ein Beispiel werfen, wie das Resultat aussehen kann. 5.9. Dokumentieren der Prozedur 77 Nun beginnen wir damit, unsere Prozedur für die Dokumentation aufzubereiten. Öffnen Sie dazu bitte den ”setState” Prozedurknoten, falls dieser nicht ohnehin noch geöffnet (77) ist. Wie Sie in Abbildung 5.9 sehen können, verwendet die Prozedur zwei Parameter. Um für diese eine Dokumentation zu erzeugen, fügen wir zwei Zeilen in das Feld ”Bemerkung” des Knotens ein. Diese beginnen mit dem Schlüsselwort @param, gefolgt von dem Parameternamen und einer passenden Beschreibung. @param ist ein spezielles Schlüsselwort, um die Beziehung der Beschreibung zu den Prozedurparametern anzuzeigen. Zusätzlich kann eine allgemeine Beschreibung der Prozedur am Anfang des Bemerkungsfelds eingefügt werden. Beachten Sie, dass es möglich ist, mit HTML Tags den Text zu formatieren. Abbildung 5.9: Kommentare für die Package Dokumentation Fügen Sie nun bitte entsprechende Kommentare in Ihre ”setState” Prozedur ein, so dass wir die Erzeugung der Dokumentation starten können. Der Generierungsprozess ist sehr einfach. Öffnen Sie einfach über das Menü Datei→HTML/XML Pkgdoc erstellen... . Den folgenden Dialog zur Auswahl von Optionen zur Generierung können Sie unverändert mit ”OK” bestätigen. Anschließend sollte automatisch Ihr Standard-Browser erscheinen (Sie müssen möglicherweise manuell zu ihm wechseln, falls dieser sich nicht 5.9. Dokumentieren der Prozedur 78 automatisch in den Vordergrund schiebt) und das Folgende präsentieren. Abbildung 5.10: Die Package Dokumentation Wir sehen die Gliederung des Dokumentes in drei Teile. Die Package-Übersicht, die Prozedur-Übersicht und die detaillierte Beschreibung des Packages ”checkbox”. Im Package ”checkbox” gibt es die Prozedur ”setState” mit dem allgemeinen Beschreibungstext und seinen Parametern. Mit dem Pkgdoc Feature können Sie sehr einfach eine wertvolle Beschreibung von Packages und Prozeduren erstellen, speziell wenn Sie allgemeine Funktionalität z.B. 5.10. Abspeichern der Testsuite 79 in einer Bibliothek zur Verfügung stellen wollen. Solch eine Bibliothek ist auch Teil der (86) QF-Test Distribution. Sie wird ausführlich in Kapitel 7 behandelt. Sie können nun ein wenig mit den Möglichkeiten der Pkgdoc Generierung spielen. Zum Beispiel können Sie einen allgemeinen Beschreibungstext zum Package ”checkbox” hinzufügen und andere Schlüsselworte wie @version, @author, @result, @throws ausprobieren. Eine vollständige Liste der Tags finden Sie im Handbuch. Hinweis Sie können die Package Dokumentation in QF-Test auch automatisch im Batch-Modus generieren. Details über die entsprechenden Kommandozeilenargumente finden Sie im Handbuch. 5.10 Abspeichern der Testsuite Inzwischen sind Sie auf dem Weg zur Entwicklung fortgeschrittener Testsuiten weit voran gekommen. Nehmen Sie sich die Zeit, die Arbeit, die Sie bisher in Ihre Testsuite gesteckt haben, zu sichern. Speichern Sie dazu die Testsuite durch Auswahl des Menüeintrags Datei→Speichern unter... unter dem Namen utils.qft ab. Den Namen können Sie natürlich frei wählen, aber wir werden im folgenden Kapitel noch darauf Bezug nehmen. Hinweis Wenn Sie QF-Test ohne Lizenz im Demo Modus evaluieren, können Sie Ihre Testsuite nicht speichern. Sie können jederzeit eine vollwertige Evaluationslizenz von Quality First Software GmbH anfordern. Näheres hierzu finden Sie im Web auf der QFTest Download Seite1 . Im nächsten Kapitel werden wir noch tiefer in QF-Test einsteigen und beginnen, die Möglichkeiten zum Erstellen von modularen Bibliotheken zu erforschen. Dieser Punkt ist gut geeignet um eine Pause einzulegen und QF-Test auf eigene Faust (und mit Hilfe des Handbuchs!) zu erkunden, um das bisher Gelernte zu vertiefen. 1 http://www.qfs.de/de/qftest/download.html Kapitel 6 Modularisierung [30-45 Min] In diesem Kapitel werden wir auf den Konzepten aufbauen, die Sie in den vorhergehenden Kapiteln gelernt haben. Unser Ziel ist es, Ihnen zu zeigen, wie Sie Testsuiten modularisieren können. Die Features, die wir im Folgenden beschreiben, sind um einiges komplexer als die der vorhergehenden Kapitel, so dass Sie ein gründliches Verständnis des bereits abgedeckten Stoffs mitbringen sollten. Wenn Sie damit beginnen, Testsuiten für Ihren spezifischen Bedarf zu erstellen, werden Sie häufig in eine Situation kommen, in der Sie immer wieder die gleichen - oft redundanten - Schritte durchführen. So benötigt vielleicht Suite A häufig die Verwendung von bestimmten Menüeinträgen in Ihrem SUT, die Suite B ebenso verwendet. Anstatt dieselbe Prozedur in beiden Testsuiten vorzuhalten ist es wesentlich praktischer und zuverlässiger, einen gemeinsamen Ort für diese Prozedur zu haben. Dieser Gedanke führt uns zum Konzept einer ”Hilfssuite” oder besser ”Bibliothek”, die gemeinsame Prozeduren für den Aufruf aus beliebigen anderen Testsuiten zur Verfügung stellt. Ihre Suite utils.qft, die Sie hoffentlich nach dem vorherigen Kapitel abgespeichert haben, wird uns nun als Bibliothek mit Hilfsprozeduren dienen. Auf diese können dann andere Testsuiten bei Bedarf zugreifen. Eine solche Struktur hat den Vorteil, dass beim Aufbau neuer Testsuiten auf fertige Prozeduren zugegriffen wird, die ihre akkurate und zuverlässige Funktion bereits bewiesen haben. Diese Art der Modularisierung ist mit QF-Test einfach zu bewerkstelligen, wie wir in den folgenden Abschnitten zeigen werden. 6.1 Erstellen der Hauptsuite Erstellen Sie zunächst eine neue Testsuite über den Menüeintrag Datei→Neue Suite . In dieser Suite werden Sie im Lauf der folgenden Abschnitte einen Test für das SUT erstellen. 6.2. Was gehört wohin 81 Sie sollten auch die Suite utils.qft öffnen, die das ”checkbox” Package aus dem vorherigen Kapitel enthält. Speichern Sie Ihre neue Datei im selben Verzeichnis wie utils.qft, damit Sie relative Pfadnamen verwenden können, wenn eine Testsuite die andere referenziert. Den Dateinamen selbst können Sie frei wählen. 6.2 Was gehört wohin Falls Ihr SUT noch nicht läuft, starten Sie es jetzt. Dabei werden Sie feststellen, dass die Knoten zum Start des SUT sich noch immer in utils.qft befinden. Eine echte Bibliothek sollte aber keinen direkten Bezug zum SUT haben, da sie auch von anderen Testsuiten benutzt werden kann, die andere SUTs testen. Wenn Sie zum Beispiel zwei SUTs ’A’ und ’B’ zu testen haben, würden Sie zunächst eine Testsuite für jedes SUT erstellen. Beide SUTs könnten aber Kontrollkästchen enthalten, die mit Hilfe der Prozeduren in utils.qft ein- und ausgeschaltet werden können. Daher sollte utils.qft allgemein gehalten werden. Im aktuellen Zustand enthält utils.qft Elemente, die es direkt mit dem SUT ”Options demo” verbinden. Dies sind zum einen die Knoten ”Vorbereitung” und ”Aufräumen”, (53) die Sie in Abschnitt 4.1 erstellt haben und zum anderen der Inhalt des ”Fenster und Komponenten” Knotens. Diese SUT-spezifische Information ist jetzt für die Bibliothek irrelevant und sollte in die Testsuite verschoben werden, die das SUT testet. (53) Gehen Sie also wie in Abschnitt 4.1 beschrieben vor, um die ”Vorbereitung” und ”Aufräumen” Knoten sowie die Unterknoten von ”Fenster und Komponenten” in Ihre neue Testsuite zu verschieben. Achten Sie dabei darauf, die Ausschneiden Funktion anstelle von Kopieren zu verwenden, damit die Knoten auch wirklich aus der Bibliothek utils.qft entfernt werden. Wenn Sie fertig sind, sollte Ihre neue Suite jetzt genau wie (55) das Skelett in Abbildung 4.1 aussehen. Außerdem können Sie noch die Prozeduraufrufe aus utils.qft entfernen, so dass diese Suite jetzt auf das Minimum reduziert ist, wie es die folgende Abbildung zeigt: Abbildung 6.1: Bibliothek utils.qft 6.3. 6.3 Erstellen einer Testsequenz 82 Erstellen einer Testsequenz In diesem Abschnitt werden Sie eine neue Testsequenz für das SUT in Ihrer neuen Testsuite erstellen. Es wird eine einfache Sequenz werden: Selektieren des ”Miscellaneous” Knotens im SUT und Deaktivieren des Kontrollkästchens ”Boolean option”. Fügen Sie in Ihrer Testsuite nach dem Knoten ”Vorbereitung” einen neuen ”Sequenz” Knoten mittels Einfügen→Sequenz Knoten→Sequenz ein. Geben Sie ihm einen Namen, z.B. ”Deselect Checkbox”. Klappen Sie den Knoten aus, so dass Sie neue Knoten darunter einfügen können. Abbildung 6.2: Die Sequenz ”Deselect checkbox” Klicken Sie nun den ”Aufnahme starten” Knopf , um eine neue Sequenz von Events aufzunehmen. Selektieren Sie im Fenster des SUT den Knoten ”Miscellaneous” im ”Preferences” Baum. Sie sollten daraufhin das ”Miscellaneous Options” Unterfenster im rechten Teil des SUT sehen. Wechseln Sie zurück zu Ihrer Testsuite und stoppen Sie . die Aufnahme mit dem ”Aufnahme beenden” Knopf In der neu aufgenommenen Sequenz im ”Extras” Knoten sollten Sie nur einen einzelnen Event sehen, nämlich den Klick auf den ”Miscellaneous” Knoten. Verschieben Sie diesen ”Event” Knoten in Ihren ”Sequenz” Knoten, der nun in etwa so aussehen sollte: Abbildung 6.3: ”Sequenz” Knoten mit aufgezeichnetem Mausklick 6.4 Aufruf einer Prozedur in der Bibliothek Der nächste Schritt besteht darin, einen Prozeduraufruf zum Deaktivieren des Kontroll(76) kästchens zu erstellen. Fügen Sie wie in Abschnitt 5.8 einen ”Prozeduraufruf” Knoten 6.5. Include Datei hinzufügen 83 für die Prozedur ”checkbox.setState” ein. Diesen müssen wir nun allerdings etwas modifizieren, da sich die Prozedur jetzt in einer anderen Testsuite befindet. Zum Aufruf einer Prozedur in einer anderen Testsuite verwendet QF-Test folgende Konvention: Der Name der Suite wird dem Namen der Prozedur - durch ein ’#’ Zeichen getrennt - vorangestellt. In unserem Beispiel ist die korrekte Form utils.qft#checkbox.setState. Vergessen Sie nicht, die Variablen wie in (76) Abschnitt 5.8 anzugeben, mit dem Wert ”false” für ”select”. Abbildung 6.4: Prozeduraufruf in die Suite utils.qft 6.5 Include Datei hinzufügen Es gibt noch eine einfachere Methode, als Prozeduraufrufe mit einer expliziten Referenz der Testsuite wie in utils.qft#checkbox.setState zu versehen. QF-Test ermöglicht es, Testsuiten als Include Dateien einzubinden und diese damit zu einem festen Teil Ihrer gesamten Teststruktur zu machen. Eine Include Datei ist eine implizite Referenz einer anderen Testsuite. Wenn QF-Test beim Ablauf eines Tests auf einen Prozeduraufruf ohne explizite Angabe einer Testsuite (d.h. ohne mit ’#’ vorangestellten Dateinamen) trifft, sucht es diese Prozedur zunächst in der aktuellen Testsuite. Führt diese Suche nicht zum Erfolg, werden der Reihe nach die Include Dateien der Testsuite durchsucht. Klicken Sie auf den ”Testsuite” Wurzelknoten Ihrer Suite. Unter den Attributen dieses Knotens sehen Sie eine Tabelle für ”Include Dateien”. Fügen Sie zu dieser Liste nun die Bibliothek utils.qft hinzu. Einträge in dieser Liste werden wie Variablen über die Knöpfe ”Bearbeiten”, ”Hinzufügen”, ”Löschen” etc. bearbeitet. Sie sollten jetzt in etwa Folgendes sehen: Abbildung 6.5: Eine Include Datei 6.6. Hinweis Modularisierung für verschiedene SUTs 84 Für detaillierte Informationen darüber, wie QF-Test implizite Referenzen bei Prozeduraufrufen auflöst, lesen Sie bitte den Abschnitt Auflösen von Include Dateien im Handbuch. 6.6 Modularisierung für verschiedene SUTs Erinnern Sie sich an die Diskussion zu Beginn dieses Kapitels? Eine Bibliothek wie utils.qft sollte keine direkten Bezüge zum SUT Client haben. Wenn Sie sich utils.qft aber genau ansehen, werden Sie feststellen, dass es immer noch Bezüge zum ”Options demo” gibt. Sehen Sie sich z.B. einen der ”Check Boolean: selected” Knoten an und Sie sehen eine direkte Referenz im ”Client” Attribut: Abbildung 6.6: Konstante Referenz des SUT Clients Diese direkte Referenz hindert Sie natürlich daran, die Bibliothek utils.qft aus einer anderen Testsuite mit einem anderen SUT Client zu verwenden. Doch auch hierfür gibt es eine einfache Lösung: Statt einer festen Referenz auf den SUT Client machen wir das ”Client” Attribut in allen Knoten der Bibliothek variabel, so dass es von der Testsuite, die utils.qft verwendet, gesetzt werden kann (und muss). Ändern Sie nun also überall, wo Sie eine Referenz auf den Client ”Options” finden, diese zu $(client) wie in folgender Abbildung: Abbildung 6.7: Variable Referenz des SUT Clients Dies müssen Sie mit sämtlichen Client Attributen in der gesamten Testsuite utils.qft machen. Auch diese Arbeit macht Ihnen QF-Test allerdings leicht: Selektieren Sie zunächst den ”Testsuite” Wurzelknoten und wählen Sie den Menüeintrag Bearbeiten→Ersetzen . Geben Sie bei ”Suchen nach” den Wert Options ein, bei ”Ersetzen durch” den Wert $(client) und wählen Sie bei ”Im Attribut” das Attribut Client aus. 6.6. Modularisierung für verschiedene SUTs 85 Den nächsten Schritt werden Sie sich bereits denken können. Sie müssen nun Ihre neue Testsuite so anpassen, dass der Wert der Variable ”client” definiert ist, wenn beim Ablauf der Tests eine Prozedur in utils.qft ausgeführt wird. Ein möglicher Weg dazu wäre, die ”client” Variable als Argument bei jedem Prozeduraufruf zu übergeben. Diese Lösung würde zwar durchaus funktionieren, sie erfordert aber viel Handarbeit und ist außerdem fehleranfällig. Eine wesentlich elegantere Lösung besteht darin, die Variable einmal in Ihrer Testsuite zu definieren, so dass Sie danach gar nicht mehr daran denken müssen. Selektieren Sie hierzu den ”Testsuite” Wurzelknoten Ihrer Suite und sehen Sie sich dessen Detailansicht an. In diesem Knoten können Sie Variablen definieren (unterhalb der Include Dateien und der abhängigen Dateien), die für die gesamte Testsuite Gültigkeit haben. Legen Sie nun eine Variable namens ”client” an und setzen Sie diese auf den Wert ”Options” wie folgt: Abbildung 6.8: Setzen einer Variable für die gesamte Testsuite Wenn Sie diesen Schritt abgeschlossen haben, sollten Sie sich keine Gedanken mehr um diese Variable machen müssen. Erst wenn Sie eine neue Testsuite erstellen, die utils.qft verwendet, müssen Sie diese wieder entsprechend definieren. Ihre Bibliothek ist jetzt vollständig modular. Kapitel 7 Die Standardbibliothek [30-45 Min] Wir vervollständigen das Konzept der Modularisierung in diesem Kapitel, indem wir eine Standardbibliothek mit Hilfsfunktionen vorstellen. Mit einigen der Hilfsmitteln, wie Operationen für Kontrollkästchen, sind Sie bereits vertraut. Andere Hilfsmittel werden für Sie neu sein. Die folgenden Abschnitte behandeln jede dieser Operationen im Detail. Es gibt verschiedene Dinge in diesem Kapitel zu lernen. Als Wichtigstes werden wir eine verwendbare Hilfsbibliothek begutachten (tatsächlich leitet sich die besprochene Bibliothek von einer Version ab, die innerhalb von Quality First Software GmbH für Regressionstests von QF-Test verwendet wird). Im Prozess des Analysierens der enthaltenen Operationen werden sich Ihnen vielleicht auch Ideen aufdrängen, wie Sie Ihre eigenen Testsuiten besser modularisieren und den ganzen Testprozess vereinfachen können. Die Prozeduren in der Bibliothek sollten mit allen Standard-Java/Swing und Eclipse/SWT Applikationen arbeiten, d.h. sie sind unabhängig von einem bestimmten SUT entwickelt worden. Deshalb sollten sie sich auch problemlos mit Ihrem SUT einsetzen lassen. Die Bibliothek ist in der Datei qfs.qft enthalten und ist Teil der QF-Test Distribution. Um die Bibliothek qfs.qft in Ihre Testsuite einzubinden, klicken Sie auf den ”Testsuite” Wurzelknoten Ihrer Suite. Unter den Attributen dieses Knotens sehen Sie eine Tabelle für ”Include Dateien”. Fügen Sie zu dieser Liste nun die Bibliothek qfs.qft hinzu. Eine Pfadangabe ist nicht notwendig, da das include Verzeichnis von QF-Test automatisch im Bibliothekspfad (siehe auch Referenzteil des Handbuchs) enthalten ist. Nun können Sie bei jedem Prozeduraufruf auch Prozeduren aus dieser Bibliothek auswählen. Zusätzlich zur folgenden Beschreibung der Standardbibliothek innerhalb des Tutorials gibt es eine HTML-Dokumentation in einem javadoc ähnlichen Format. Die Datei heisst qfs.html und liegt im Verzeichnis qftest-4.0.6/include. 7.1. 7.1 Das SUT zum Testen 87 Das SUT zum Testen Wie gesagt, die vorgestellte Standardbibliothek ist SUT unabhängig. Jedoch werden wir zu ihrer Demonstration ein SUT verwenden, das genau für diesen Zweck entwickelt wurde. Öffnen Sie die Testsuite StdLibDemo.qft. Sie befindet sich im Verzeichnis qftest-4.0.6/doc/tutorial Ihrer QF-Test Installation, dort wo auch das aus früheren Kapiteln bereits bekannte Options.qft liegt. Nun sollten Sie das Folgende sehen: Abbildung 7.1: Die Testsuite StdLibDemo.qft Starten Sie die SUT Applikation durch Ausführen des gezeigten Knotens ”Vorbereitung: Start the application”. Einige Augenblicke später sollte das Fenster des SUTs erscheinen - falls nicht, versteckt es sich vermutlich hinter der Testsuite. 7.2. Die Standardbibliothek 88 Abbildung 7.2: Das SUT zum Testen der Standardbibliothek 7.2 Die Standardbibliothek Öffnen Sie nun auch die Bibliothek selbst, also die Datei qfs.qft, die sich im Verzeichnis qftest-4.0.6/include Ihrer QF-Test Installation befindet. Das folgende Bild gibt einen Überblick der enthaltenen Packages. 7.2. Die Standardbibliothek 89 Abbildung 7.3: Die Standardbibliothek Die Bibliothek enthält im wesentlichen Prozeduren zur Erleichterung der Arbeit mit bestimmten Java/Swing und Eclipse/SWT Komponenten. Im ersten Teil dieses Kapitels werden wir uns mit dem ”swing” und dem ”swt” Package befassen und anschließend auf die übrigen nützlichen Packages zurückkommen. Der Aufbau des ”swing” und ”swt” Packages ist der gleiche, deshalb werden die darin enthaltenen Prozeduren nur einmal beschrieben. In allen Prozeduren unserer Bibliothek werden Sie die Verwendung der Variable $(client) bemerken. Dies ist ein Standardmechanismus, um Testsuiten unabhängig von einem spezifischen SUT zu gestalten. Für die Benutzung der Standardbibliothek wird vorausgesetzt, dass ein gültiger Wert für $(client) gesetzt wird, bevor eine ihrer Prozeduren verwendet werden kann. Als Beispiel einer möglichen Wertzuweisung für die Variable $(client) sehen wir die Attribute des Wurzelknotens ”Testsuite” von StdLibDemo.qft, welche die Variable global für die ganze Testsuite setzt. Somit haben alle Knoten, die innerhalb dieser Testsuite aufgerufen werden (wie Prozeduraufrufe nach qfs.qft), Zugriff auf die Variable. 7.2. Die Standardbibliothek 90 Abbildung 7.4: Setzen der $(client) Variable Sie können den Wert von $(client) aber auch im Aufruf einer Prozedur in qfs.qft setzen. Dieses Vorgehen kann sinnvoll sein, wenn Sie mit mehr als einem SUT arbeiten. Beachten Sie in diesem Zusammenhang auch, dass es keine Defaultwerte für die $(client) Variable in den Prozeduren von qfs.qft geben kann, da dies die unerwünschte Festlegung auf ein SUT bedeuten würde. Die von der Standardbibliothek verwendete $(client) Variable muss von Ihnen gesetzt werden! Hinweis Sie mögen im obigen Bild bemerkt haben, dass wir qfs.qft in die Beispiel-Testsuite inkludiert haben, ohne eine direkte Angabe des Verzeichnisses, in dem die Datei enthalten ist. Dies ist möglich, weil das include Verzeichnis Ihrer QF-Test Distribution einen voreingestellten Bibliothekspfad von QF-Test bildet. Das bedeutet, dass alle Testsuiten, die sich in diesem Verzeichnis befinden, direkt in alle Ihre eigenen Testsuiten inkludiert werden können. Weitere Bibliothekspfade können unter Bearbeiten→Optionen→Allgemein→Bibliothek definiert werden. Die vollständige Beschreibung aller Packages und Prozeduren, inklusive Parametern und Rückgabewerten, enthält die HTML Dokumentation, die auch über das Hilfe Menü erreichbar ist. Die neueste Version ist auch online verfügbar unter http://www.qfs.de/include/qfs_pkgdoc/qfs_pkgdoc.html. 7.3. Ausgewählte Packages und Prozeduren 7.3 91 Ausgewählte Packages und Prozeduren Wir werfen nun einen genaueren Blick auf eine Anzahl ausgewählter Packages und Prozeduren der Standardbibliothek. Bitte beachten Sie, dass folgenden Beispiele hauptsächlich auf qfs.swing-Prozeduren basieren. Die Prozeduren aus qfs.swt können auf die gleiche Art und Weise verwendet werden. Prozeduren, die Java/Swing bzw. Eclipse/SWT spezifisch implementiert sind, werden am Ende des Kapitels beschrieben. 7.3.1 Das Checkbox Package Wir beginnen nun mit der genaueren Betrachtung des swing.checkbox bzw. swt.checkbox Packages. Dies ist ein guter Startpunkt, da die enthaltenen Prozeduren Ihnen sehr vertraut vorkommen sollten, wenn Sie die Testsuite (80) utils.qft im Kapitel 6 dieses Tutorials entwickelt haben. Folgende Prozeduren sind innerhalb des Packages verfügbar: • select Selektiert ein Kontrollkästchen. Wenn das Kontrollkästchen sich bereits im ausgewählten Zustand befindet, wird keine Aktion ausgeführt. • deselect Deselektiert ein Kontrollkästchen. Wenn das Kontrollkästchen sich bereits im nicht-ausgewählten Zustand befindet, wird keine Aktion ausgeführt. • set Setzt ein Kontrollkästchen auf den angegebenen Zustand (true oder false). Für jede dieser Prozeduren wird die QF-Test ID der Kontrollkästchenkomponente als variables Argument übergeben. Die Bibliothek kümmert sich um die Überprüfung, dass der Zustand des Kontrollkästchens wie erwartet gesetzt wurde. Eine beispielhafte Anwendung der Prozeduren finden Sie unterhalb des Knotens ”Checkbox Tests” innerhalb von StdLibDemo.qft. 7.3. Ausgewählte Packages und Prozeduren 92 Abbildung 7.5: Beispielanwendung des qfs.swing.checkbox Packages Die Anwendung der anderen Prozeduren in diesem Package folgt dem generellen Modell, wie es hier gezeigt wurde. 7.3.2 Das Combobox bzw. Combo Package Die Packages swing.combobox bzw. swt.combo enthalten Prozeduren, um Werte in einer Combobox zu selektieren. Folgende Prozeduren sind innerhalb des Packages verfügbar: • setValue Selektiert einen Wert in der Liste der Combobox. • setValueViaSUTScript Setzt den Wert der Combobox anhand eines SUT-Skriptes. Für Swing wird setSelectedItem() und für SWT select() verwendet. 7.3.3 Das General Package Die Packages swing.general bzw. swt.general enthalten allgemeine Prozeduren für GUI-Elemente. Folgende Prozeduren sind innerhalb des Packages verfügbar: • clickAtComponent Führt einen Mausklick auf einer Komponente durch, aber nur, wenn ein entsprechender Parameter gesetzt wird. • doClick Führt einen Mausklick auf einer Komponente durch. 7.3. Ausgewählte Packages und Prozeduren 93 • setLocation Setzt die Position der Komponente mittels angegebenen Koordinaten. • setSize Setzt die Größe der Komponente. 7.3.4 Das List Package Die Packages swing.list bzw. swt.list enthalten allgemeine Prozeduren für Listen. Folgende Prozeduren sind innerhalb des Packages verfügbar: • getItemCount Zählt die Einträge einer Liste. 7.3.5 Das Menu Package Die Packages swing.menu und swt.menu erlauben es Ihnen, in einfacher Weise Einträge (und auch Kontrollkästchen) in Menüs oder Untermenüs auszuwählen (bzw. zu setzen). Es gibt folgende Prozeduren: • selectItem Wählt einen Eintrag in einem Menü aus. • selectSubItem Wählt einen Eintrag in einem Untermenü aus. • setCheckItem Setzt den Zustand eines Kontrollkästchens in einem Menü (true oder false). • setSubCheckItem Setzt den Zustand eines Kontrollkästchens in einem Untermenü (true oder false). An alle diese Prozeduren muss die QF-Test ID der Menükomponente wie auch des Eintrags bzw. Kontrollkästchens übergeben werden. Die Benutzung variiert leicht, abhängig von der jeweiligen Art der Prozedur. Werfen Sie einen Blick auf die beispielhafte Benutzung im ”Menu Tests” Knoten. Ein Aufruf von ”setSubCheckItem” sieht beispielsweise so aus: 7.3. Ausgewählte Packages und Prozeduren 94 Abbildung 7.6: Beispiel eines Aufrufs von menu.setSubCheckItem Hier sehen wir die variablen Argumente, die beim Prozeduraufruf gebraucht werden. Die Argumente sind wie folgt organisiert: menu -> item -> subCheckItem (checkItemValue), die folgende Implementierung im SUT repräsentiert: Options -> Tree -> Enable (true) Der Ablauf im SUT macht den Ablauf noch klarer: 7.3. Ausgewählte Packages und Prozeduren 95 Abbildung 7.7: Auswählen eines Kontrollkästchens in einem Untermenü des SUTs 7.3.6 Das Popup Menu Package Popup Menüs (Kontextmenüs) sind normalen Menüs sehr ähnlich, da auch sie Einträge, Untermenüs und Kontrollkästchen enthalten können. Der primäre Unterschied ist die Art, wie ein Popup Menü aktiviert wird. Dies geschieht in der Regel durch Rechtsklicken auf eine (mit einem Kontextmenü ausgestattete) Komponente. Die Packages swing.popupmenu bzw. swt.popupmenu enthalten den gleichen Satz an Prozeduren wie swing.menu bzw. swt.menu. Die Implementierung unterscheidet sich ein wenig. Bevor die Prozeduren aus dem swing.popupmenu bzw. swt.popupmenu Package aufgerufen werden können, muss gewährleistet sein, dass das zu steuernde Kontextmenü sauber geöffnet wurde. Betrachten Sie das folgende Beispiel im SUT: 7.3. Ausgewählte Packages und Prozeduren 96 Abbildung 7.8: Auswählen eines Untermenüeintrags in einem Kontextmenü Wir haben dieses Beispiel durch folgenden Test in StdLibDemo.qft implementiert. Der erste Knoten öffnet das Kontextmenü. Anschließend folgt der Prozeduraufruf, gefolgt von einem Check auf das Ergebnis. Abbildung 7.9: Beispielaufruf von popupmenu.setSubItem 7.3.7 Das SWT/Sash Package Das Package swt.sash enthält Prozeduren org.eclipse.swt.widgets.Sash. für Komponenten • moveSash Bewegt einen Sash um eine angegebene Distanz. der Klasse 7.3. Ausgewählte Packages und Prozeduren 97 • moveSashTo Bewegt einen Sash auf eine angegebene Position. 7.3.8 Das Table Package Die Packages swing.table und swt.table enthalten Hilfsprozeduren für Tabellen. • getRowCount Zurückliefern der aktuellen Zeilenanzahl der Tabelle. Diese Prozedur verwendet die Methode getRowCount() für Swing bzw. getItemCount() für Eclipse/SWT. • getColumnCount Zurückliefern der aktuellen Spaltenanzahl der Tabelle. Diese Prozedur verwendet die Methode getColumnCount() für Swing und für Eclipse/SWT. • resizeColumn Verändern der Breite einer gegebenen Tabellenspalte. Achtung Diese Prozedur ist zur Zeit nur für Swing verfügbar. • selectCell Selektiert eine angegebene Tabellenzelle. Der Trick bei der Implementierung ist es, sich mit einem ”Geometrie auslesen” Knoten die aktuelle Spaltenbreite zu holen und von dort mit der Maus die Spalte passend größer oder kleiner zu ziehen. 7.3.9 Das Table/Selection Package Die Packages swing.table.selection und swt.table.selection enthalten Prozeduren, um Tabellenzeilen zu selektieren. • deselectAllRows Deselektiert alle Tabellenzeilen. • deselectRow Deselektiert eine Tabellenzeile, die durch den Index identifiziert wird. • deselectRowRange Deselektiert einen Bereich von Tabellenzeilen, die durch Index identifiziert werden. • selectAllRows Selektiert alle Tabellenzeilen. • selectRow Selektiert eine Tabellenzeile, die durch Index identifiziert wird. • selectRowRange Selektiert einen Bereich von Tabellenzeilen, die durch Index identifiziert werden. Der Trick bei der Implementierung ist es, sich mit einem ”Geometrie auslesen” Knoten die aktuelle Spaltenbreite zu holen und von dort mit der Maus die Spalte passend größer oder kleiner zu ziehen. 7.3. Ausgewählte Packages und Prozeduren 7.3.10 98 Das TabbedPane bzw. CTabfolder Package Die Packages swing.tabbedpane bzw. swing.ctabfolder beinhalten Prozeduren für Tabbedpanels oder Tabfolders. • closeTab Schließe eine Tab mit dem ”X” Knopf. Dies funktioniert u.U. nicht für alle Implementierungen von TabbedPanes and CTabfolder. • selectTab Selektiert einen angegeben Tab in einem CTabFolder. 7.3.11 Das Text Package Die Packages swing.text bzw. swt.text stellen Hilfsfunktionen für Textfelder und -bereiche zur Verfügung. Möglicherweise sind Sie während der Entwicklung von Testsuiten bereits an Stellen gekommen, wo solch eine Funktionalität hilfreich gewesen wäre. • setText Setzt den Wert eines angegebenen Textfeldes. • clearField Löscht ein Textfeld (JTextField). Die Prozedur kann nicht für Textbereiche verwendet werden. • clearArea Löscht einen Textbereich (JTextArea). Die Prozedur kann nicht für Textfelder verwendet werden. Hinweis Diese Prozeduren sind inzwischen nahezu redundant, da ”Texteingabe” Knoten die Zielkomponente vorher bei Bedarf selbst löschen. Trotzdem können die Prozeduren sich vielleicht in der einen oder anderen Situation als hilfreich erweisen. Jede der Prozeduren benötigt die QF-Test ID des Textfeldes/-bereichs als Argument. Nachfolgend sehen wir einen Test in StdLibDemo.qft, in dem ein Textbereich im SUT manipuliert wird. Hierbei wird zuerst der Textbereich gelöscht. Anschließend werden zwei Zeilen Text eingegeben. Der Inhalt des Textbereichs wird dann auf den erwarteten Inhalt hin überprüft. Zum Schluss wird der Textbereich erneut gelöscht und überprüft, dass er auch wirklich leer ist. Abbildung 7.10: Beispiel für den Einsatz von text.clearArea 7.3. Ausgewählte Packages und Prozeduren 7.3.12 99 Das Tree Package Die Bibliothek stellt in den Packages swing.tree bzw. swt.tree einige einfache Prozeduren zur Manipulation von Bäumen zur Verfügung. Das sind: • collapse Einklappen eines Baumknotens. Ist der Knoten bereits eingeklappt, wird keine Aktion ausgeführt. • collapseNode Einklappen eines Baumknotens. Ist der Knoten bereits eingeklappt, wird keine Aktion ausgeführt. Diese Prozedur besitzt drei einzelne Parameter für Baum und Knoten • expand Ausklappen eines Baumknotens. Ist der Knoten bereits expandiert, wird keine Aktion ausgeführt. • expandNode Ausklappen eines Baumknotens. Ist der Knoten bereits expandiert, wird keine Aktion ausgeführt. Diese Prozedur besitzt drei einzelne Parameter für Baum und Knoten. • selectNode Selektiert einen angegebenen Baumknoten. Jede der Prozeduren benötigt die QF-Test ID des Baumknotens als Argument. Als Beispiel sehen wir nachfolgend einen Prozeduraufruf, um einen Baumknoten zu expandieren: 7.3. Ausgewählte Packages und Prozeduren 100 Abbildung 7.11: Beispiel für die Benutzung von tree.expand Beachten Sie bitte, dass wir eine Komponente eines Baumknoten verwenden, die wir bereits früher aufgenommen haben. Wenn Sie in den Knoten ”Fenster und Komponenten” von StdLibDemo.qft schauen, können Sie die einzelnen Komponenten des Baums, die wir aufgenommen haben, sehen: 7.3. Ausgewählte Packages und Prozeduren 101 Abbildung 7.12: Aufgenommene Komponenten des Baums 7.3.13 Das Cleanup Package Die Packages swing.cleanup bzw. swt.cleanup bieten eine gute Unterstützung für das Aufräumen der SUT Umgebung, wenn unerwartet eine Exception auftritt. Stellen Sie sich zum Beispiel vor, dass eine Exception geworfen wird, während auf ein Menü des SUTs zugegriffen wird. Die Exception bewirkt, dass der Ausführungspfad innerhalb Ihrer Testsuite zu einem Exception Handler umgeleitet wird - oder an einen ”impliziten” Exception Handler. Das bedeutet, dass der normale Ausführungspfad, der das geöffnete Menü in der Regel wieder ordnungsgemäß geschlossen hätte, unterbrochen wurde. Ohne eine entsprechende Aktion kann dieses Menü geöffnet bleiben und somit andere Ereignisse an das SUT blockieren. Hier sehen Sie die Liste von verfügbaren Prozeduren innerhalb des Packages: • closeAllModalDialogs Stellt sicher, dass modale Dialoge des SUTs geschlossen werden. Nur für Swing verfügbar! • closeAllDialogs Stellt sicher, dass alle Dialoge des SUTs geschlossen werden. Nur für Swing verfügbar! 7.3. Ausgewählte Packages und Prozeduren 102 • closeAllDialogsAndModalShells Stellt sicher, dass alle Dialoge und modalen Shells geschlossen werden. Nur für Eclipse/SWT verfügbar! • closeAllMenus Schließt alle offenen Menüs des SUT. • implicitExceptionHandler Kann als generischer Handler benutzt werden für die Behandlung von implizit gefangenen Exceptions. Die ersten beiden Prozeduren sollten in ihrer Bedeutung relativ klar sein. Die dritte Prozedur implicitExceptionHandler bildet eine Zusammenfassung der ersten beiden Prozeduren des Packages. Das macht sie zu einem guten Default Handler für ihre Testsuite, um unerwartete Exceptions sauber zu behandeln. Das Konzept der Behandlung von impliziten Exceptions ist von großer Bedeutung, denn eine Exception in einem einzigen Testfall soll nicht zum Beenden des gesamten Testlaufs führen. Lediglich der aktuelle Testfall muss abgebrochen werden, dann sollte es mit dem nächste Testfall weitergehen. Aus diesem Grund wird eine Exception innerhalb eines Testfalls auf dieser Ebene gefangen und nicht nach oben propagiert, um den Abbruch des gesamten Testlaufs zu verhindern. Der Fehlerstatus wird jedoch stets korrekt im Protokoll und Report festgehalten. Benutzt der Testfall eine Abhängigkeit, wird die Exception an den Catch Knoten derselben übergeben, falls ein solcher vorhanden ist. Diese Art der Behandlung von Exceptions (und Fehlern) wird im Kapitel Abhängigkeiten des Handbuchs erklärt. 7.3.14 Das Swing/Filechooser Package Das Package qfs.swing.filechooser unterscheidet sich von den bisher beschriebenen Packages der Bibliothek. Es dient nicht nur zur Manipulation des DateiauswahlDialogs (der JFileChooser von Swing, um genau zu sein), sondern hilft auch bei der Aufnahme und beim Identifizieren von Komponenten innerhalb des Dialogfensters. Wir werden zuerst die Prozeduren auflisten und dann mehr ins Detail gehen. Der FileDialog von SWT wird im Package qfs.swt.fileDialog behandelt, welches weiter unten beschreiben wird. • selectFile Wählt eine Datei im Dateiauswahl-Dialog. • enableNameResolver Installiert den NameResolver für JFileChooser (Erklärung folgt unten). • disableNameResolver Deinstalliert den NameResolver für JFileChooser. 7.3. Ausgewählte Packages und Prozeduren 103 Die erste Prozedur (selectFile) ist ziemlich eindeutig. Sie übergeben einfach den gewünschten Dateinamen. Die Auswahl wird über das entsprechende Textfeld des Dialogs durchgeführt. Ihre Testsuite muss zuvor den Filechooser-Dialog geöffnet haben. Hier ein Beispiel: Abbildung 7.13: Beispiel für qfs.swing.filechooser.selectFile die Benutzung von Jedoch wird selectFile nicht funktionieren, bevor Sie den NameResolver installiert haben! Wir werden dies im Folgenden tun und erklären. Die Prozedur enableNameResolver installiert und aktiviert eine Erweiterung von QFTest, die JFileChooserResolver heißt. Dieser NameResolver wird Ihnen beim Umgang mit dem Swing JFileChooser Dialog wichtige Hilfe leisten. Der JFileChooserResolver ist ein Standard NameResolver, wie er im Kapitel ”NameResolver” in der Technischen Referenz im Handbuch beschrieben wird. Die Notwendigkeit entsteht dadurch, dass Komponenten innerhalb des JFileChooser Dialogs keine durch die Java Methode setName zugewiesenen Namen besitzen. Dies kann zu einiger Verwirrung bei der Entwicklung von Tests führen, da die selben (Unter)Komponenten in unterschiedlichen Auswahl-Dialogfenstern auftauchen können. Zum Beispiel gibt es das Eingabefeld ”Dateiname” sowohl im ”Öffnen” als auch ”Speichern” Dialog. Für QF-Test selbst ist dies kein Problem. Es hat wirkungsvolle Algorithmen für die Aufnahme und Erkennung von Komponenten und lässt sich deshalb von nicht-eindeutigen Komponenten ohne Namen in verschiedenen Fenstern nicht durcheinander bringen. Für den Entwickler jedoch führt die Verwaltung der Komponenten zu Verwirrung. Werfen Sie einen Blick auf die Liste der aufgenommenen Komponenten der Beispielapplikation für die zwei Auswahl-Dialoge ”Öffnen” und ”Speichern”: 7.3. Ausgewählte Packages und Prozeduren 104 Abbildung 7.14: Aufgenommener JFileChooser Dialog und Komponenten Wie Sie sehen, identifiziert QF-Test die Komponenten korrekt und vergibt eindeutige Identifier, so wie ”textFile_Name:2” - die ”2” repräsentiert die zweite aufgenommenen Komponente dieses Typs. Stellen Sie sich nun vor, Sie hätten eine größere Anzahl von verschiedenen JFileChooser Dialogen, jede mit ihrer eigenen Liste von Komponenten, die getrennt gepflegt werden müssen. In solch einer Umgebung Testfälle zu entwickeln, kann schnell sehr mühsam und unübersichtlich werden. Zurück zum NameResolver. Dies ist ein Feature, das es innerhalb QF-Test ermöglicht, Komponenten ohne Namen, wie einen JFileChooser Dialog, dynamisch mit Namen zu versehen, so als ob dies bereits im Java Quellcode der Applikation durch setName passiert wäre. Das Resultat ist, dass JFileChooser ganz normal behandelt werden kann. Es bedeutet, dass nur eine Liste mit den Komponenten für JFileChooser notwendig ist, um die gesamte Anzahl aller in Ihrer Applikation verwendeten Ausprägungen von JFileChooser zu steuern. Hier sehen Sie ein Beispiel. Abbildung 7.15: Benutzung des NameResolvers Wir sehen in der folgenden Implementierung der Prozedur selectFile, dass generische Komponenten referenziert werden: 7.3. Ausgewählte Packages und Prozeduren 105 Abbildung 7.16: Implementierung von selectFile mit generischen Komponenten In der Tat brauchen Sie in Ihrer eigenen Testsuite gar keine Komponenten für irgend einen JFileChooser Dialog pflegen, wenn Sie den NameResolver nutzen. Die generischen Komponenten sind in qfs.qft gespeichert: Abbildung 7.17: Generische JFileChooser Komponenten in qfs.qft Beachten Sie, dass in unserer Beispiel-Testsuite StdLibDemo.qft der NameResolver durch die Vorbereitungs- und Aufräumsequenz aktiviert bzw. deaktiviert wird. Das ist eigentlich zuviel des Guten und nur zu Demonstrationszwecken. Normalerweise genügt es, den NameResolver einmal zu installieren und es dabei zu belassen. Es gibt auch keine direkte Notwendigkeit, den NameResolver zu deaktivieren. 7.3.15 Das Swing/Optionpane Package Das Package qfs.swing.optionpane enthält Prozeduren für den Zugriff auf Dialoge vom Typ JOptionPane. JOptionPane ist die Swing Komponente, die zum Anzeigen von kleinen Nachrichtendialogen verwendet wird, typischerweise Fehler-, Warnung, Frage- oder Informationsdialoge. Abbildung 7.18: Ein JOptionPane Dialog 7.3. Ausgewählte Packages und Prozeduren 106 Die erste Gruppe von Prozeduren erlaubt das Feststellen des Dialogtyps: • isErrorDialog Prüft, ob der Dialog ein Fehlerdialog ist. • isInfoDialog Prüft, ob der Dialog ein Infodialog ist. • isWarningDialog Prüft, ob der Dialog ein Warnungsdialog ist. • isQuestionDialog Prüft, ob der Dialog ein Fragedialog ist. • isPlainDialog Prüft, ob der Dialog ein Dialog ohne Typ ist. • isOptionPane Prüft, ob der Dialog ein OptionPane Dialog ist. Die nächste Gruppe hilft bei Auslesen von Daten aus dem Dialog: • getTitle Liefert den Titel des Dialogs. • getOptionPaneMessageType Liefert den Dialogtyp als String. • getMessage Liefert den Nachrichtentext. • checkTitle Prüft den Titel gegen einen vorgegebenen Wert. • checkMessage Prüft den Nachrichtentext gegen einen vorgegebenen Wert. Dann gibt es eine Gruppe die Verfügbarkeit von spezifischen Buttons zu prüfen und diese zu drücken: • hasOkButton Prüft, ob ein OK Button vorhanden ist. • hasYesButton Prüft, ob ein Ja Button vorhanden ist. • hasNoButton Prüft, ob ein Nein Button vorhanden ist. • hasCancelButton Prüft, ob ein Abbrechen Button vorhanden ist. • clickOkButton Drückt den OK Button. • clickYesButton Drückt den Ja Button. • clickNoButton Drückt den Nein Button. • clickCancelButton Drückt den Abbrechen Button. 7.3. Ausgewählte Packages und Prozeduren 107 Zum Schluss bleibt noch eine Gruppe zum Aktivieren und Deaktivieren des JOptionPane NameResolvers. Die Notwendigkeit eines NameResolvers für diese Komponente resultiert aus der Tatsache, dass sowohl die Dialoge, als auch deren Kindkomponenten wie Buttons und Labels typischerweise keine Namen haben. So muss QF-Test sie anhand ihrer Titel und Labeltexte identifizieren, wodurch für jede Ausprägung der JOptionPane ein Komponentenknoten angelegt wird. Dies führt sehr schnell zu einer großen Anzahl an solchen Elementen und ist aus Gründen der Übersichtlichkeit und Wartbarkeit nicht wünschenswert. Schauen wir nun auf die Prozeduren, die die Schnittstellen beschreiben. Sie sind sehr einfach: • enableNameResolver Installiert den JOptionPane NameResolver. • disableNameResolver De-installiert den JOptionPane NameResolver. Die Prozedur enableNameResolver installiert und aktiviert eine Erweiterung von QFTest bezeichnet als JOptionPaneResolver. Dieser NameResolver ermöglicht eine einfache Behandlung von JOptionPane Dialogen. Es ist ein Standard NameResolver, wie er in der Technischen Referenz des Handbuchs erklärt wird. All die anderen Prozeduren im optionpane Package aktivieren (und deaktivieren) automatisch den NameResolver. Nur wenn Sie direkt mit der JOptionPane Komponente interagieren wollen, müssen Sie den Resolver selbst aktivieren. Typischerweise genügt es hierbei, den NameResolver am Beginn des Testlaufs, am besten direkt nach dem Warten auf Client Knoten zu installieren. Ein De-installieren ist in der Regel nicht erforderlich. Zusätzlich zu den Prozeduren stellt qfs.qft generische Komponenten zur Verfügung, welche das Aufnehmen von OptionPane Komponenten und deren Wartung überflüssig machen. Die folgende Grafik zeigt die Komponenten: 7.3. Ausgewählte Packages und Prozeduren 108 Abbildung 7.19: Generische OptionPane Komponenten in qfs.qft Sie sehen, dass 5 verschieden Typen von Dialogen unterstützt werden: • Error • Info • Warning • Question • Plain Stellvertretend für alle ist der Plain Dialog geöffnet, um seinen Inhalt preiszugeben. Wir sehen vordefinierte Komponenten für mögliche Buttons (standard und benutzerdefinierte) und Labels, die den Nachrichtentext beinhalten. In unserer Demo Testsuite StdLibDemo.qft finden Sie einen kleinen Test hierfür unter dem ”OptionPane” Testknoten, der ein wenig mit den beiden ”About” Dialogen aus dem ”Help” Menü der Demoapplikation spielt. Es gibt sowohl einen Test mit als auch ohne NameResolver. Schauen Sie sich bitte vor allem die Komponenten unter ”Fenster und Komponenten” an, auf die die Tests zugreifen. Ohne NameResolver müssen zwei leicht unterschiedliche Komponenten verwaltet werden, während mit NameResolver nur eine der vordefinierten Komponenten in qfs.qft notwendig ist. Anmerkung: Der beschriebene NameResolver ist in der Lage, die üblicherweise benutzten Ausprägungen der JOptionPane ordentlich auf die vordefinierten Komponenten in qfs.qft abzubilden. Spezielle Formen von JOptionPane können jedoch dazu führen, dass QF-Test separate Komponenten aufzeichnen muss. 7.3. Ausgewählte Packages und Prozeduren 7.3.16 109 Das SWT/ColorDialog Package Das Package qfs.swt.colorDialog dient zur Manipulation des Farbauswahl-Dialogs (die org.eclipse.swt.widgets.ColorDialog SWT Komponente). Hier sehen Sie die Liste von verfügbaren Prozeduren innerhalb des Packages: • selectColor Wählt eine Farbe im Farbauswahl-Dialog. 7.3.17 Das SWT/FileDialog Package Das Package qfs.swt.fileDialog dient zur Manipulation des Dateiauswahl-Dialogs (die org.eclipse.swt.widgets.FileDialog SWT Komponente). Hier sehen Sie die Liste von verfügbaren Prozeduren innerhalb des Packages: • selectFile Wählt eine Datei im Dateiauswahl-Dialog. 7.3.18 Das SWT/DirectoryDialog Package Das Package directorydialog ist ähnlich zum FileDialog Package. Es stellt Prozeduren bereit, um mit dem DirectoryDialog (die org.eclipse.swt.widgets.DirectoryDialog SWT Komponente) zu arbeiten. Hier sehen Sie die Liste von verfügbaren Prozeduren innerhalb des Packages: • selectDirectory Wählt ein Verzeichnis im Verzeichnisauswahl-Dialog. 7.3.19 Das SWT/Instrument Package Das Package qfs.swt.instrument enthält Prozeduren, um Ihre Eclipse/RCP und SWT-standalone Anwendung korrekt zu instrumentieren. Hier eine Liste aller verfügbaren Prozeduren: • setup Instrumentiert eine Eclipse/RCP basierte oder standalone SWT Applikation, wie im Kapitel zu SWT Instrumentierung im Handbuch beschrieben. 7.3.20 das AWT/Menu Package Das Package qfs.awt.menu enthält Prozeduren, um mit AWT-Menüs zu arbeiten. AWT-Menüs sind die einzigen AWT-Komponenten, welche nicht von QF-Test standardmäßig unterstützt werden. 7.3. Ausgewählte Packages und Prozeduren 110 Hier sehen Sie die Liste von verfügbaren Prozeduren innerhalb des Packages: • selectItem Selektiert einen bestimmten Menüeintrag. 7.3.21 Das Run-log Package Das Package qfs.run-log enthält Prozeduren, um Meldungen in das Protokoll zu schreiben. Hier sehen Sie die Liste von verfügbaren Prozeduren innerhalb des Packages: • logError Schreibt eine Fehlermeldung ins Protokoll. • logWarning Schreibt eine Warnung ins Protokoll. • logMessage Schreibt eine Meldung ins Protokoll. 7.3.22 Das Run-log.Screenshots Package Das qfs.run-log.screenshots Package enthält Prozeduren, die Bildschirmabbilder ins Protokoll schreiben und einige Hilfsprozeduren. Hier sehen Sie die Liste von verfügbaren Prozeduren innerhalb des Packages: • getMonitorCount Liefert die Anzahl der angeschlossenen Monitore. • logScreenshot Schreibt ein Bildschirmabbild des aktuellen Monitors ins Protokoll. • logImageOfComponent Schreibt ein Bildschirmabbild einer Komponente ins Protokoll. • logScreenshotOfMonitor Schreibt ein Bildschirmabbild eines angegebenen Monitors ins Protokoll. 7.3.23 Das Shellutils Package Das qfs.shellutils Shell-Kommandos. Package beinhaltet Prozeduren für die wichtigsten Hier sehen Sie die Liste von verfügbaren Prozeduren innerhalb des Packages: • copy Kopiert eine angegebene Datei oder ein Verzeichnis an eine neue Stelle. • deleteFile Löscht eine angegebene Datei. 7.3. Ausgewählte Packages und Prozeduren 111 • exists Prüft, ob eine angegebene Datei oder ein Verzeichnis existiert. • getBasename Gibt den Dateinamen der Datei zurück. • getParentDirectory Gibt die Verzeichnisstruktur der Datei zurück. • mkdir Erzeugt ein Verzeichnis. Es werden auch Verzeichnisse neu angelegt im Pfad, die nicht existieren. • move Verschiebt eine angegebene Datei oder ein Verzeichnis. • touch Erzeugt eine Datei. • removeDirectory Löscht ein angegebenes Verzeichnis. 7.3.24 Das Utils Package Das Package qfs.utils enthält nützliche Prozeduren für häufig auftretende Anforderungen der Testentwicklung. Hier sehen Sie die Liste von verfügbaren Prozeduren innerhalb des Packages: • getDate Gibt einen String zurück, der ein Datum enthält. Standardmäßig wird das aktuelle Datum zurückgegeben. (Andere Daten sind konfigurierbar.) • getTime Gibt einen String zurück, der eine Zeit enthält. Standardmäßig wird die aktuelle Zeit zurückgegeben. (Andere Zeiten sind konfigurierbar.) • logMemory Schreibt den aktuellen Speicherverbrauch ins Protokoll. • printVariable Gibt den Inhalt einer spezifizierten Variable auf der Konsole aus. • printMessage Gibt den Inhalt einer angegebenen Nachricht auf der Konsole aus. • writeMessageIntoFile Schreibt einen angegebenen String in eine angegebene Datei. 7.3.25 Das Database Package Das Package qfs.database enthält nützliche Prozeduren, um mit Datenbanken zu arbeiten. Bitte beachten Sie, dass der Datenbanktreiber für die Datenbankverbindung entweder im Pluginverzeichnis von QF-Test oder in der Umgebungsvariable CLASSPATH vor dem Start von QF-Test sein muss. 7.3. Ausgewählte Packages und Prozeduren 112 Für weitere Informationen über den Aufbau einer Datenbankverbindung kontaktieren Sie einen Entwickler oder werfen Sie einen Blick auf www.connectionstrings.com. Hier sehen Sie die Liste von verfügbaren Prozeduren innerhalb des Packages: • executeSelectStatement Führt einen angegebenen SQL-Select-Befehl aus. Das Ergebnis wird in eine globale Variable ”resultRows” im Jython Variablenstack geschrieben. • executeStatement Führt einen angegebenen SQL Befehl aus. Hier kann jedes beliebige SQL Kommando ausgeführt werden. 7.3.26 Das Check Package Das qfs.check enthält Prozeduren, die Checks ausführen. Hier sehen Sie die Liste von verfügbaren Prozeduren innerhalb des Packages: • checkEnabledStatus Überprüft, ob eine Komponente en- bzw. disabled ist. Die Prozedur schreibt einen Fehler ins Protokoll im Fehlerfall. • checkSelectedStatus Überprüft, ob eine Komponente selektiert bzw. nicht selektiert ist. Die Prozedur schreibt einen Fehler ins Protokoll im Fehlerfall. • checkText Überprüft den Text einer Komponente. Die Prozedur schreibt einen Fehler ins Protokoll im Fehlerfall. 7.3.27 Das Databinder Package Das Package qfs.databinder enthält Prozeduren zur Ausführung innerhalb eines Datentreiber Knotens, um Daten für datengetriebenes Testen zu binden. Hier sehen Sie die Liste von verfügbaren Prozeduren innerhalb des Packages: • bindList Bindet eine Liste von Werten an eine Variable. Die Werte sind durch Leerzeichen oder das als Parameter übergebene Trennzeichen getrennt. • bindSets Bindet Sätze von Werten an einen Satz von Variablen. Die Sätze von Werten sind durch Zeilenumbrüche getrennt, die Werte innerhalb eines Satzes durch Leerzeichen oder das als Parameter übergebene Trennzeichen. 7.3. Ausgewählte Packages und Prozeduren 7.3.28 Das Web Package Das qfs.web Package enthält Prozeduren, die das Webtesten unterstützen. Folgende Prozeduren sind innerhalb des Packages verfügbar: • startBrowser Startet einen SUT-Client in einem Browser. 113 Kapitel 8 Arbeiten mit komplexen GUI Elementen [30-45 Min] Bis zu diesem Zeitpunkt haben wir einfache Java GUI Komponenten wie Buttons, Auswahl- oder Textfelder behandelt. Wir wollen uns nun komplexeren Komponenten zuwenden, die wiederum selbst Unterelemente enthalten. Klassische Beispiele dafür sind Tabellen und Bäume. Betrachten wir die Knoten von Bäumen. Ein Knoten ist im Sinne von Java selbst noch keine GUI Komponente, er ist lediglich eine graphische Repräsentation von wenigen Daten. Diese technische Unterscheidung bringt uns im Hinblick auf das Testen jedoch nicht weiter, da das Verhalten eines Baumknotens genau so wichtig ist, wie das einfacher GUI Komponenten. Zur Lösung dieser Problematik verwendet QF-Test spezielle ”Element”-Knoten, die solche Unterelemente komplexer GUI Komponenten abbilden. Wir werden sie in diesem Kapitel genau beleuchten und auch die von QF-Test verwendete Zugriffssyntax vorstellen. 8.1 Das ”Items” Demo In diesem Abschnitt werden wir eine einfache Anwendung, die verschiedene komplexe Komponenten enthält, als SUT verwenden. Wir haben das Programm ”ItemsDemo” genannt und es ist Teil des Jar Archivs Ihrer QF-Test Distribution. Sie können entweder selbst einen Startknoten erstellen anhand der Grafik unten oder einfach die Testsuite items.qft aus den Tutorial-Verzeichnis laden, die eine passende Startsequenz unter den ”Extrasequenzen” enthält. 8.1. Das ”Items” Demo 115 Abbildung 8.1: Der Start Java SUT Client Knoten für das ”ItemsDemo” Starten Sie anschließend das SUT. Das Ergebnis sollte folgendermaßen aussehen: 8.2. Eindimensionale komplexe Komponenten 116 Abbildung 8.2: Das Fenster des ”ItemsDemo” 8.2 Eindimensionale komplexe Komponenten Wir beginnen mit der Analyse der einfachsten komplexen Elemente. Es ist eine eindimensionale Liste, die durch die Java Klasse JList repräsentiert wird. Im Fenster des SUT sehen Sie eine JList als erste Komponente mit der Bezeichnung ”Sample List”. Starten Sie eine Aufnahme und führen Sie einige Mausklicks auf die Listenelemente aus. Nach dem Anhalten der Aufnahme sollten Sie eine Sequenz sehen, die der folgenden entspricht: Abbildung 8.3: Mausklick Operationen auf eine JList Wählen Sie bitte einen der aufgenommenen ”Mausklick” Knoten aus und sehen Sie sich 8.2. Eindimensionale komplexe Komponenten 117 die referenzierte Komponente an. Abbildung 8.4: Referenz auf ein JList Element Die Referenz stellt sich intuitiv im Format ”Eltern.Kind” (oder auch ”Parent.Child”) dar. Im diesem Fall ist ”List” der Name der Elternkomponente (die JList) und ”list_item_2” ist der Name des individuellen (Kind) Elementes der Liste. Schauen wir uns an, wie die Komponente in QF-Test abgespeichert wird. Mit diesem Knoten weiterhin selektiert, wählen Sie bitte ”Komponente finden” aus dem über die rechte Maustaste erreichbaren Kontextmenü (auch Strg-W führt zum Ziel). Nun sollten Sie eine expandierte Liste der gespeicherten Komponenten des SUT unterhalb des Knotens ”Fenster und Komponenten” der Testsuite sehen. Der ausgewählte Knoten sollte sich äquivalent dem folgenden präsentieren: Abbildung 8.5: Der JList Element Knoten Was wir hier sehen ist ein Knotentyp, der als ”Element” bezeichnet wird. Er wird speziell dazu benutzt, um Unterelemente von komplexen Komponenten zu beschreiben. Ein Elementknoten besteht aus zwei Hauptteilen: Dem Parent, zu dem er gehört und dem Index des Elements. Betrachten Sie bitte die Eigenschaften des Knotens in der Detailansicht: 8.2. Eindimensionale komplexe Komponenten 118 Abbildung 8.6: Die Eigenschaften des JList Elements Hier sehen wir die QF-Test ID der Komponente (Mit der QF-Test ID der Parentkomponente vorangestellt) und einen Primärindex. Weil die Liste eine eindimensionale Struktur ist, brauchen wir vorerst nur einen Index. Wenn wir uns im nächsten Abschnitt Tabellen ansehen, wird der Sekundärindex ins Spiel kommen. Der Primärindex wird hier durch einen String repräsentiert, der dem aktuellen Textinhalt des Listenelementes im SUT entspricht. Diese Beschreibung ist für die meisten Anwendungen angemessen, jedoch kann sie sich als unvorteilhaft für solche Listen erweisen, bei denen sich der Text der Elemente permanent ändert. Um diesem Problem vorzubeugen, bietet Ihnen QF-Test zwei andere Beschreibungsmöglichkeiten an: Die erste referenziert das Element als einen numerischen Index (beginnend mit 0) innerhalb der Liste. Ändern Sie also bitte den Primärindex ”list element 2” in den Knotenattributen in den äquivalenten Wert ”1” und wählen Sie anschließend das Auswahlfeld ”Als Zahl” um die Interpretation des Feldes umzuschalten. Abbildung 8.7: JList Element mit numerischem Index Die zweite Alternative der Repräsentation des Index ist die Darstellung als regulärer Ausdruck (Regexp = Regular Expression). Hier führt QF-Test eine entsprechende textu- 8.3. Zweidimensionale komplexe Komponenten 119 elle Suche über die Listenelemente im SUT durch, solange, bis ein passendes Muster gefunden ist. Hier ein Beispiel: Abbildung 8.8: JList Element mit regulärem Ausdruck als Index Der benutzte reguläre Ausdruck [0-9a-zA-Z ]*2 beschreibt eine willkürliche Anzahl von Zahlen, Buchstaben oder Leerzeichen, gefolgt von der Zahl ”2” am Ende. Eine andere Möglichkeit wäre der Ausdruck .*2. Weitere Informationen zum Thema ”Reguläre Ausdrücke” finden Sie in der Technischen Referenz des Handbuchs unter ”Technische Details zu verschiedenen Themen”. Versuchen Sie nun Ihre aufgenommene Sequenz erneut auszuführen, nun aber mit den geänderten Elementknoten. Wenn Sie die Änderungen der Indexreferenzen korrekt durchgeführt haben, sollte das Verhalten der Sequenz exakt gleich bleiben. 8.3 Zweidimensionale komplexe Komponenten Wir werden uns nun komplexeren Strukturen zuwenden - einer zweidimensionalen Komponente, bestens vertreten durch die Java Klasse JTable. Eine Tabelle besteht bekannterweise aus Zeilen und Spalten. Deshalb benötigt ein Element in der Tabelle zwei Indizes um sauber referenziert zu werden. Abbildung 8.9: Die Beispieltabelle ”sample table” im SUT Versuchen Sie bitte, analog wie bei der Liste, einige wenige Mausklicks auf die Elemente der Tabelle ”sample table” des SUT aufzunehmen. Stellen Sie sicher, dass Elemente aus beiden Spalten berücksichtigt werden. Nach Abschluss sollte Ihr Ergebnis analog dem folgenden sein: 8.3. Zweidimensionale komplexe Komponenten 120 Abbildung 8.10: Aufgenommene Mausklicks auf die JTable Die Knoten gleichen weitgehend denen, die wir für die JList aufgenommen hatten. Es sind einfache ”Mausklick” Knoten, die auf eine Komponente vom Typ ”Parent.Primärindex&Sekundärindex” verweisen - ”Table” ist der JTable Parent, ”Label” bzw. ”Value” ist der Primär- oder Spaltenindex und eine Nummer gibt den Sekundäroder Zeilenindex an. Das ”&” hat hierbei eine besondere Bedeutung. Es zeigt an, dass der Sekundärindex direkt auf das angegebene Tabellenelement verweist, ohne die Verwendung eines Elementknotens. Diese spezielle Syntax wird im nächsten Kapitel detailliert erklärt. Benutzen wir wieder ”Komponente finden” aus dem Kontextmenü, um zu dem aktuell gespeicherten Elementknoten zu gelangen. Abbildung 8.11: Gespeicherte Elementknoten für die JTable Da für den Sekundärindex keine Elementknoten notwendig sind, wurden auch keine aufgenommen. Es sind also nur solche für den Primärindex, sprich die Spalten ”Label” und ”Value” vorhanden. Wenn wir einen Blick in die Details des ”Label” Elementknotens werfen, sehen wir, dass darin auch nur der Primärindex verwendet wird. 8.4. Elementknoten oder Syntax 121 Abbildung 8.12: Eigenschaften eines Elementknotens der JTable 8.4 Elementknoten oder Syntax Das vorausgehende Kapitel beschrieb die Verwendung von Elementknoten in QF-Test. Es gibt jedoch noch einen weiteren Weg, um auf Elemente komplexer Komponenten zuzugreifen. Dieses kann erreicht werden durch die Angabe der Parent-Komponente, erweitert durch eine spezielle Syntax zur Angabe der Unterkomponente. Dieser Typ von Syntax wird in QF-Test als ’direkter Zugriff’ auf das Element definiert. Äquivalent zur Repräsentation in Elementknoten gibt es drei Typen von Syntax: • @ - textuell • & - numerisch • % - regulärer Ausdruck (120) Im Sekundärindex der Mausklicks in Abbildung 8.10 findet diese spezielle Syntax in der numerisch Form mittels ”&” Anwendung. Es wird in diesem Fall kein Elementknoten benötigt. Bitte versuchen Sie den Unterschied der verschiedenen Repräsentationen zu verstehen. Ob die Beschreibung von Unterelementen mittels Element Knoten oder mittels Syntax erfolgt, ist aus Sicht von QF-Test völlig gleichwertig. Jede Methode hat ihre Berechtigung. Elementknoten eignen sich besonders gut für statische Werte, während die Syntax in allen Fällen mit einer gewissen Variabilität besser geeignet ist. QF-Test versucht, bei der Aufnahme die am besten geeignete Variante zu wählen, jedoch mag in seltenen Fällen eine Anpassung sinnvoll sein. Mit Hilfe der zugehörigen Optionen (siehe Handbuch) können Sie genau festlegen, auf welche Weise Unterelemente aufgenommen werden. Als abschließendes Beispiel zeigt das folgende Bild eine ”Mausklick” Sequenz, bei der auch der Primärindex als Syntax formuliert ist. Die Funktionalität bleibt die gleiche. 8.5. Die Bedeutung der Eindeutigkeit 122 Abbildung 8.13: Mausklicks mit Syntax für direkten Zugriff 8.5 Die Bedeutung der Eindeutigkeit Wir halten hier für einen Moment an, um erneut die Wichtigkeit von eindeutig referenzierenden Elementen innerhalb komplexer Komponenten hervorzuheben. Wie es die Natur von Komponenten ist, in ihrer Komplexität zu wachsen, so steigt gleichermaßen die Komplexität des Referenzierens auf die Elemente der Komponenten. Bei den vorhergehenden Beispielen (Listen und Tabellen) ist die Struktur relativ einfach. Jedoch können selbst in diesen Komponenten identische Einträge auftauchen. Betrachten wir die folgende Tabelle: Abbildung 8.14: Tabelle mit identischen Elementen Da identische Elemente auftauchen können (und werden), müssen Sie genau betrachten, wie Ihre Testsuite solche Tabellen behandelt. Was könnte sich ändern und was bleibt konstant? Die Antwort bestimmt von welchem Typ die Referenzen sein sollten, die Sie innerhalb der Tabelle benutzen. Dies ist der Grund, warum QF-Test die Zeilennummer als Sekundärindex verwendet, wenn die Aufnahme im intelligenten Modus erfolgt. Der Modus, der die Form festlegt, in der QF-Test Unterelemente aufnimmt, kann angepasst werden über Bearbeiten→Optionen... und anschließend ”Aufnahme” -> ”Unterelemente”. Im nächsten Abschnitt werden wir uns die wohl komplexeste Komponente vornehmen, bei welcher die Behandlung von potentiell identischen Elementen von kritischer Bedeutung ist. 8.6. 8.6 Bäume 123 Bäume Bäume sind eine spezielle Ausprägung von komplexen Komponenten, da sich ihr hierarchischer Aufbau nicht gut auf eine lineare Struktur abbilden lässt. Die Eindeutigkeit eines Knotens erfordert also eine spezielle Betrachtung. Durch den Satz an Hilfsmitteln und Konzepten, die Sie in den vorausgehenden Kapiteln gelernt haben, ermöglicht QF-Test eine gut beherrschbare Steuerung von Bäumen. Von spezieller Bedeutung ist die Einführung des ’/’ Operators, der wie ein Pfad-Trennzeichen in einer Dateisystem-Hierarchie arbeitet. Wir wollen es einfach ausprobieren. Wie zuvor nehmen Sie bitte ein paar Mausklicks auf den ”sample tree” Baum des SUT auf. Sie sollten in etwa Folgendes erhalten: Abbildung 8.15: Aufgenommene Mausklicks auf einen JTree Zuerst versuchen Sie einfach, mit der aufgenommenen Sequenz ein wenig zu spielen und sie anzupassen, um zu verstehen, wie Bäume behandelt werden. Klicks auf das +/- Symbol zum Ein- und Ausklappen von Baumknoten werden mit negativen X-Koordinaten aufgezeichnet, da der Klick ja links vom Baumknoten platziert wird. Für die Wiedergabe sind solche Klicks nicht notwendig, denn QF-Test expandiert den Baum automatisch für Sie, vorausgesetzt die ensprechende Wiedergabeoption ist gesetzt. Wir wollen nun die Syntax betrachten, z.B. im Klick auf den Knoten ”/JTree/colors/yellow”. Der Pfadoperator (’/’) wird benutzt, um den Weg innerhalb des Baumes zum gewünschten Knoten zu beschreiben. Dieses Schema hat den enormen Vorteil, dass damit unmittelbar das Problem der Eindeutigkeit gelöst ist. Knoten mit gleichem Namen in unterschiedlichen Zweigen des Baumes sind sauber getrennt benennbar. Das einzige Problem der Eindeutigkeit das bleibt, ist, wenn Baumknoten mit gleichem Namen im gleichen Zweig existieren können (z.B. wenn es zwei ”yellow” Knoten in ”/JTree/colors” gibt). In diesem Fall bleibt uns der bewährte Mechanismus des Referenzierens als Zahl. Möglichen Änderungen in der Indizierung eines JTree Knotens begegnet man am besten durch direkten Zugriff, wie er im vorausgegangenen Kapitel vorgestellt wurde. Es kann einer der Operatoren ’@’, ’&’ oder ’%’ verwendet werden, um direkten Zugriff textueller oder numerischer Natur bzw. eines regulären Ausdrucks zu erreichen. Hier sieht 8.6. Bäume 124 man, wie eine direkte numerische Referenz aussieht: Abbildung 8.16: Direkte numerische Referenz auf einen JTree Knoten Das war’s! Nun sollten Sie in der Lage sein, Ihren Weg durch die Komplexität dieser Komponenten zu steuern. Kapitel 9 Nun ist es Zeit, Ihre eigene Anwendung zu starten Nachdem wir so viel Zeit mit all den Beispielanwendungen verbracht haben, sind Sie nun wirklich bereit, Ihre eigene Applikation zu starten (falls Sie das nicht schon zwischendurch getan haben). Der Schnellstart-Assistent, welcher über das Menü Extras→Schnellstart-Assistent... erreichbar ist, hilft Ihnen bei dieser Aufgabe. Folgen Sie einfach den Schritten innerhalb des Assistenten, um eine passende Startsequenz zu erzeugen. Bitte schauen Sie auch ins Handbuch Kapitel 3 ”Schnellstart”. Dann ist es an der Zeit, das Gelernte in die Tat umzusetzen - kurze Sequenzen von Events und Checks aufnehmen, Prozeduren erzeugen etc., um eine eigene Testbibliothek aufzubauen. Damit endet der Basisteil in diesem Tutorial. Teil II Web testen mit QF-Test Kapitel 10 Bearbeiten einer Beispiel Testsuite [30-45 Min] 10.1 Starten von QF-Test und Laden einer Testsuite Nach dem Starten von QF-Test laden Sie bitte unser erstes Beispiel. Dazu öffnen Sie den Dateiauswahl-Dialog über das Menü Datei→Öffnen... und wechseln nach qftest-4.0.6/doc/tutorial/web, welches sich unterhalb Ihrer QF-Test Installation befindet. Dort wählen Sie bitte die Datei webdemo.qft aus und öffnen diese. QFTest präsentiert Ihnen die Testsuite wie im folgenden Bild dargestellt: 10.1. Starten von QF-Test und Laden einer Testsuite 128 Abbildung 10.1: Das Fenster der Testsuite webdemo.qft. Der linke Bereich des Hauptfensters enthält eine Baumstruktur, welche die Testsuite repräsentiert. Rechts befindet sich die Detailansicht des Knotens, der im Baum gerade markiert ist. (Falls die Detailansicht bei Ihnen nicht zu sehen sein sollte, aktivieren Sie diese bitte über das Menü Ansicht→Details anzeigen .) Im unteren Fensterbereich befindet sich das Terminal, welches die Standardausgaben des zu testenden Clients protokolliert. Die Anzeige des Terminals kann mittels Ansicht→Terminal→Anzeigen kontrolliert werden. Mit Hilfe des Baumes können Sie durch die Testsuite navigieren und einzelne Knoten auswählen, für die dann jeweils die Details im rechten Fensterbereich eingeblendet werden. Die oberste Ebene des Baumes besteht in diesem Fall aus folgenden Knotentypen: • ”Testsuite” - Dies ist der Wurzelknoten einer jeden Testsuite. Alle weiteren Knoten sind ihm untergeordnet. • ”Testfallsatz” - Dieser Knotentyp dient zur Zusammenfassung und Strukturierung von Testfällen. • ”Prozeduren” - Unterhalb dieses Knotens können Prozeduren abgelegt werden. • ”Extrasequenzen” - Dieser Knoten dient als Spielwiese zum Ausprobieren und 10.2. Starten des Browsers 129 Zusammenstellen von Tests. Hier können beliebige Knoten abgelegt werden, unabhängig von den normalen Einschränkungen. Beim Ausführen einer Testsuite als ganzes wird dieser Knoten nicht mitausgeführt. • ”Fenster und Komponenten” - An dieser Stelle legt QF-Test die Informationen zu den Elementen und der Struktur der zu testenden Webseite ab. Diese werden automatisch während der Aufnahme des Tests gesammelt und sind notwendig für das Auffinden der Komponenten bei der Wiedergabe des Tests. Klicken Sie bitte doppelt auf den Knoten ”Testfallsatz: Web demo”, um ihn zu expandieren. Unser Testfallsatz enthält primär drei Testfälle: ”Clickstream”, ”Text check” und ”Selected test”. Umgeben werden die Testfälle von einem ”Vorbereitung”/”Aufräumen” Paar, welches ein sauberes System als Ausgangsbasis für die Testfälle garantiert. Abbildung 10.2: Der Inhalt des Knotens ”Testfallsatz: Web demo”. In den folgenden Abschnitten werden wir Funktion und Zweck der einzelnen Knoten erklären. 10.2 Starten des Browsers Zuerst wollen wir den Vorbereitungsknoten genauer unter die Lupe nehmen. Expandieren Sie ihn dazu bitte, wie im folgenden Bild gezeigt. 10.2. Starten des Browsers 130 Abbildung 10.3: Der Knoten ”Vorbereitung: Start browser”. Es werden drei Kindknoten sichtbar: • ”Browser starten” - startet den Browser, der für die Webtests verwendet werden soll. • ”Warten auf Client” - wartet bis der Browser erfolgreich gestartet ist und Verbindung zu QF-Test herstellt. • ”Warten auf Komponente” - wartet auf das Erscheinen einer bestimmten Komponente der Webseite, hier dem Hauptdokument index.html. Damit kann davon ausgegangen werden, dass das System under Test (SUT) d.h. Kombination aus Browser und geladener Seite bereit für Tests ist. Der Umgang mit Komponenten und ihre Bedeutung werden später noch genauer erläutert. Selektieren Sie nun bitte den ”Browser starten” Knoten. 10.2. Starten des Browsers 131 Abbildung 10.4: Der Knoten ”Browser starten”. Nun wollen wir uns die Knotenattribute im rechten Fensterbereich genauer ansehen: • Im obersten Feld ”Client” wird ein eindeutiger Bezeichner für unsere Testapplikation definiert. Er lässt sich frei wählen und wird im Weiteren immer wieder als Referenz gebraucht. • Das zweite Feld ”URL” enhält die vollständige Bezeichnung der Webseite, mit der die Tests beginnen sollen. In unserem Fall wird eine lokale Seite im Dateisystem verwendet, deshalb beginnt der Bezeichner mit file://. Danach folgen zwei variable Anteile: ${qftest:suite.dir} wird zu dem Verzeichnis expandiert, in welchem sich die aktuelle Testsuite befindet. ${system:user.language} resultiert in de oder en, je nach Spracheinstellung des Benutzers, also Ihnen. Den Schluss bildet dann die eigentliche Webseite index.html. 10.2. Starten des Browsers 132 • Wichtig ist noch das vierte Feld, welches die Art des Browsers angibt, der für die Tests benutzt werden soll. ”ie” bedeutet hierbei Internet Explorer, Alternativen sind ”mozilla” für Mozilla Firefox oder ”chrome” für Google Chrome. Fall Sie ”mozilla” angeben, müssen Sie zusätzlich das Verzeichnis ihrer Firefox Installation im Feld ”Verzeichnis der Browser-Installation” angeben. Die anderen Browser werden automatisch gefunden und das Feld ignoriert. • Die Angaben für Breite und Höhe im Attribut ”Geometrie des Browser-Fensters” stellen sicher, dass die Webseite vollständig sichtbar ist. Dies ist jedoch nur Kosmetik und keine Voraussetzung für die Funktion der Tests. • Die restlichen Felder werden für das folgende Beispiel nicht benötigt und sind deshalb leer. Ganz unten befindet sich noch ein Feld ”Bemerkung”, das Kommentare aufnehmen kann. Wenn Sie möchten, können Sie auch einen Blick in die Details der anderen beiden Knoten in der Vorbereitungssequenz werfen. Wir wollen nun die Anwendung wirklich starten. Markieren Sie dazu bitte den Knoten ”Vorbereitung”, doch belassen Sie ihn aufgeklappt. Dann klicken Sie den Knopf ”Wie. Anschließend lässt sich der Ablauf in der Baumansicht verfolgen. Der dergabe” gerade aktive Knoten wird während der Wiedergabe durch ”->” markiert. Auch sehen Sie die Ausgaben des SUT Clients im Terminal. Nach Abschluss der Startsequenz erscheint das Browser-Fenster mit der Demoseite am Bildschirm. Es ist vollständig unter Kontrolle und den wachsamen Augen von QF-Test. Hinweis Wenn das Browser-Fenster auf Ihrem Bildschirm nicht zu sehen ist, oder nur kurzzeitig erscheint, dann befindet es sich vermutlich hinter dem Hauptfenster von QF-Test. Am besten positionieren Sie beide Fenster nebeneinander, so dass Sie beide zur gleichen Zeit sehen können. 10.3. Ein erster Testfall - Mausklick Sequenz 133 Abbildung 10.5: Die WebDemo Seite. 10.3 Ein erster Testfall - Mausklick Sequenz Als Nächstes wollen wir einen Blick auf einen ersten Testfall werfen. Der Testfallknoten ”Clickstream” beinhaltet eine Sequenz von Mausklicks auf alle Einträge im Menü der Webseite. Wenn Sie den Testfallknoten ”Clickstream” öffnen, sehen Sie darin enthalten eine Sequenz: 10.3. Ein erster Testfall - Mausklick Sequenz 134 Abbildung 10.6: Der Testfallknoten ”Clickstream” besteht aus einer Sequenz. Bevor Sie den Test ausführen, stellen Sie bitte sicher, dass die ”Willkommen” Seite im Webdemo ausgewählt ist. Dann markieren Sie den ”Clickstream” Testfallknoten und drücken den ”Wiedergabe” Knopf . Die Testsequenz sollte ohne Probleme durchlaufen. Das Testergebnis wird während und nach dem Testlauf in der Statuszeile am unteren Rand des QF-Test Hauptfensters angezeigt und lautet ”Keine Fehler”. Daneben gibt es auch noch Zähler für Anzahl und Ergebnis der wiedergegebenen Testfälle. In unserem Fall war das nur einer, der fehlerfrei lief, was einer Erfolgsquote von 100% entspricht. Hinweis Wenn Sie den Mauszeiger auf dem Symbol eines Testfallzählers ruhen lassen, wird Ihnen eine entsprechende Beschreibung angezeigt. Eine Auflistung aller Testfallzähler finden Sie im Kapitel Aufnahme und Wiedergabe des Handbuchs. Um anschließend nachzuvollziehen, was wir während der Wiedergabe gesehen haben, werfen wir einen Blick in die Sequenz ”Menu items” innerhalb des ”Clickstream” Testfalls: Abbildung 10.7: Die Sequenz ”Menu items” enthält Mausklicks auf die Einträge in der Menüleiste. Dort sehen wir, dass die Sequenz mit einem Mausklick beginnt. Sie sehen auch die Koordinaten der Klicks relativ zum Nullpunkt der dahinter in eckigen Klammern angegebenen Komponente. Beim ersten Klick ist das z.B. der zweite Menüeintrag ”Texteingabe”. Nach dem ersten Mausklick bewirkt der ”Warten auf Komponente” Knoten, dass auf das Erscheinen der neuen Webseite gewartet wird. Nach dem erfolgreichen Laden der Seite, wird mit der Sequenz fortgefahren mit dem nächsten Mausklick. In gleicher Form 10.4. Einige Tipps zwischendurch 135 geht es weiter mit den verbleibenden Menüeinträgen bis wieder die Seite ”Willkommen” erreicht wird. 10.4 Einige Tipps zwischendurch Hier zwischendurch ein kleiner Tipp, wenn Sie z.B. bei einem Knotentyp nicht genau wissen, wofür er eingesetzt wird, oder auch die Bedeutung eines seiner Attribute nicht zuordnen können. QF-Test ist mit einer kontextsensitiven Hilfe ausgestattet. Bewegen Sie den Mauszeiger zu dem Element, für das Sie Hilfe wünschen und drücken Sie die rechte Maustaste. Es erscheint das Kontextmenü, bei dem es ganz unten den Eintrag Was ist das? gibt. Wenn Sie diesen auswählen, wird das entsprechende Kapitel im Referenzteil des Handbuches in Ihren Standardbrowser geladen. (Unix-Anwender können den Browser unter Bearbeiten→Optionen... im Bereich ”Allgemein” einstellen.) So finden Sie schnell die benötigte Information. Probieren Sie es doch bitte gleich mal aus. Wenn Sie nach einem Thema oder Stichwort suchen wollen, so empfehlen wir Ihnen dies in der PDF Version des Handbuchs zu tun. Die HTML Version ist dafür nicht so gut geeignet, da sie zur besseren Navigation in einzelne Seiten aufgeteilt ist. Auf jeder HTML Seite befindet sich auch eine Verknüpfung auf die PDF Version des Handbuchs, so dass der Übergang jederzeit leicht möglich ist. 10.5 Ein erster Check - Prüfen eines Textfeldes Eines der wichtigsten Konzepte in QF-Test ist das der Checks, d.h. eine Überprüfung bestimmter Elemente im SUT. Ein ”Text Check” prüft das Vorhandensein eines Textes in einer Textfeld-Komponente des SUT. Als Beispiel für eine Überprüfung - einen Check - soll durch die nachfolgend beschriebene Sequenz die Beschriftung eines Textfeldes verifiziert werden. 10.5. Ein erster Check - Prüfen eines Textfeldes 136 Abbildung 10.8: Die zu prüfende Beschriftung ”Name:”. Wenn Sie in unserer Demoseite in der Menüleiste den zweiten Eintrag ”Texteingabe” auswählen, sehen Sie ein Textfeld mit dem Label ”Name:”. Dieser Text soll geprüft werden. Im folgenden Bild sehen Sie den zugehörigen Testfallknoten ”Text check”, im expandierten Zustand: Abbildung 10.9: Der Testfall ”Text check”. Der Testfall besteht aus einem Mausklick zum Auswählen der ”Texteingabe” Seite und einem ”Check Text” Knoten zum Überprüfen des Beschriftungstextes. Kehren Sie zuerst auf die ”Willkommen” Seite im Webdemo zurück. Dann markieren Sie bitte den Testfall-Knoten ”Text check” und führen Sie ihn aus. Ein Dialog erscheint nach dem Ablauf mit der Meldung, dass ein Fehler und eine Warnung aufgetreten sind. 10.5. Ein erster Check - Prüfen eines Textfeldes 137 Abbildung 10.10: QF-Test meldet einen Fehler im Knoten ”Check Text”. Zur weiteren Diagnose wollen wir uns das Protokoll ansehen. Wir können dazu direkt den Button ”Protokoll anzeigen” drücken. Alternativ kann man das Protokoll in der Test suite mittels Wiedergabe→1. ... oder der Tastenkombination Strg-L öffnen. Es wird in einem neuen Fenster angezeigt: Abbildung 10.11: Das Protokoll für die Wiedergabe des ”Text check” Knotens. 10.5. Ein erster Check - Prüfen eines Textfeldes 138 Das Protokollfenster ähnelt im Aufbau dem einer Testsuite. Der Baum auf der linken Seite repräsentiert nun aber die zeitliche Darstellung des Testlaufs. Die Zeitachse verläuft von oben nach unten. Analog zur Testsuite befindet sich auf der rechten Seite eine Detailansicht des jeweils ausgewählten Protokollknotens im Baum. Was sofort auffällt, ist der rote Rahmen um den Wurzelknoten des Protokollbaumes. Er verrät uns, dass sich ein Fehler in einem der Kindknoten verbirgt. Die schnellste Methode, um den Fehler zu finden, bietet Bearbeiten→Nächsten Fehler finden bzw. Strg-N . Dies führt zu folgendem Bild: Abbildung 10.12: Diagnose des fehlgeschlagenen Checks ”Check Text”. Die Detailansicht auf der rechten Seite zeigt die Abweichung zwischen erwartetem und gefundenem Text. Hier sehen wir, dass der Unterschied zwischen erwartetem und erhaltenen Text der fehlende ”:” am Schluss ist. Diesen Fehler im Test haben wir natürlich zur Demonstration absichtlich eingebaut. Ein typischer Arbeitsschritt ist nun, ausgehend von dem Protokollknoten, in dem der Fehler aufgetreten ist, zurück in die Testsuite zu springen, um dort z.B. eine Anpassung im korrespondierenden Checkknoten vorzunehmen. Unter der Voraussetzung, dass der Fehler-Protokollknoten markiert ist, leistet hierbei Bearbeiten→Knoten in Testsuite finden bzw. Strg-T hervorragende Dienste. Eine Stufe weiter geht die Funktionalität des Protokollknotens mit 10.5. Ein erster Check - Prüfen eines Textfeldes 139 (138) dem Titel ”Fehlgeschlagen: Check Text” in Abbildung 10.12 , auswählbar über das Kontextmenü, das man über die rechte Maustaste öffnen kann: . Checkknoten mit erhaltenen Daten aktualisieren bzw. Strg-U Eine weitere Möglichkeit zur Fehlerdiagnose tritt in Erscheinung, wenn Sie den folgenden Knoten ”Bildschirmabbild” auswählen. Dessen Detailansicht enthält ein vollständiges Abbild des Bildschirms zum Zeitpunkt, an dem der Fehler festgestellt wurde. Es kann eine große Hilfe sein, den Zustand des SUT in diesem Moment zu sehen, um die Ursache des Fehlers zu finden. Die folgende Grafik zeigt den Knoten: Abbildung 10.13: Bildschirmabbild zum Zeitpunkt des Fehlers. Neben dem Abbild des gesamten Bildschirms speichert QF-Test auch Bilder der einzelnen Fenster des SUT. Für unser Beispiel ist dies der zweite ”Bildschirmabbild” Knoten. Diese sind dann hilfreich, falls das SUT durch eine andere Anwendung zum Fehlerzeitpunkt verdeckt ist. Hinweis Die in einem längeren Testlauf im Protokoll gesammelten Informationen können große Mengen an Arbeitsspeicher verbrauchen. Deshalb ist QF-Test so voreingestellt, dass es eine spezielle Form von kompakten Protokollen erstellt. Dabei werden nur die ca. letzten 100 Protokollknoten aufgehoben und der Rest verworfen. Informationen für Fehlerdiagnose und Reportgenerierung bleiben durchgängig erhalten. Diese Funktion ist mit der Option ”Kompakte Protokolle erstellen” über 10.6. Ein zweiter Check - Zustand eines Optionsfeldes prüfen 140 Bearbeiten→Optionen...→Protokoll→Inhalt konfigurierbar. Der Typ eines Protokolls wird auch in seinem Wurzelknoten angezeigt. Auch die Anzahl der Bildschirmabbilder, die im Protokoll gespeichert werden, ist konfigurierbar. Nun noch ein Wort zu der Warnung, die neben dem Fehler im Testlauf aufgetreten (138) wird sie mit einem gelben Rahmen um den ist. Im Protokoll von Abbildung 10.12 Knoten angezeigt. Das ist der Knoten direkt über dem fehlerbehafteten Checkknoten. Die Warnung lautet: ”Die Komponente ’textLast_name:’ hat keinen Namen”. Im Moment wollen wir diese Warnung nicht weiter verfolgen. Komponentennamen sind jedoch ein wichtiges Thema in Hinblick auf die Stabilität von Tests. Wenn Sie möchten, können Sie nun als kleine Übung den erwarteten Text im Knoten ”Check Text” der Testsuite wie oben beschrieben korrigieren. Wenn Sie den Checkknoten in der Testsuite anschließend nocheinmal ausführen, sollte kein Fehler mehr gemeldet werden. Machen Sie bitte zum Schluss diese Änderung mittels Bearbeiten→Rückgängig machen bzw. Strg-Z wieder rückgängig, um für die weitere Testdurchführung eine einheitliche Ausgangsbasis zu gewährleisten. 10.6 Ein zweiter Check - Zustand eines Optionsfeldes prüfen In der dritten Sequenz ”Selected test” werden wir überprüfen, ob sich ein Optionsfeld (Radio Button) im Zustand ”ausgewählt” befindet. Auf der Seite ”Optionsfelder & Auswahlkästchen” kann man interaktiv eine Anzahl von Buttons auswählen. Wir werden dieses verwenden, um sowohl einen erfolgreichen Check zu kreieren, als auch einen Check, der zu einem Fehler führt. Abbildung 10.14: Der ”Selected test” Knoten. Der Knoten ”Selected test” zeigt einen Mausklick, zwei Checks und dazwischen eine Auswahl. Der Klick bewirkt das Auswählen der Seite ”Optionsfelder & Auswahlkästchen”. Danach überprüft der ”Check Boolean: selected” Knoten, dass sich das erste Optionsfeld (Radio Button) im Zustand ”ausgewählt” befindet. Der ”Auswahl” Knoten schaltet die Combobox ganz oben auf der Seite auf die Option ”nicht selektiert”, was die Selektion des Knotens aufhebt. Der finale ”Check Boolean: selected” Knoten überprüft 10.7. Beenden der Applikation 141 erneut, dass sich dieser Button im Zustand ”ausgewählt” befindet. Das ist natürlich ein Widerspruch, so dass der letzte Check offensichtlich zu einem Fehler führen wird. Abbildung 10.15: Check von Auswahlfeldern im ”Web Demo”. Sie können nun die Check Knoten im Detail ansehen und die Sequenz auch starten. Vergessen Sie nicht, vorher im Webdemo auf die ”Willkommen” Seite zurück zu wechseln. 10.7 Beenden der Applikation Die Aufräumsequenz wird (wie auch die Vorbereitungssequenz) nach jedem Testfall innerhalb des umschließenden Testfallsatzes ausgeführt. Sie dient dazu, das SUT nach dem Ausführen eines Tests in einen spezifischen Zustand zu versetzen, welcher die Basis für den darauf folgenden Test bildet. Die Aufräumsequenz ist vergleichbar mit ”tear-down” Methoden in Unittests. Expandieren Sie bitte die Aufräumsequenz. Mit ”Stop browser” haben wir den endgültigen Weg gewählt und beenden im Zuge des Aufräumens einfach den Browser. 10.8. Alles in einem Rutsch 142 Abbildung 10.16: Die Aufräumsequenz ”Stop browser”. Auf den ”Programm beenden” Knoten folgt ein ”Warten auf Programmende”, um sicher zu stellen, dass der nächste Test so lange wartet bis der Browser vollständig beendet wurde. 10.8 Alles in einem Rutsch In den vergangenen Abschnitten haben wir uns Schritt für Schritt durch die einzelnen Bereiche unserer Beispieltestsuite gearbeitet. Nun ist es an der Zeit die gesamte Suite in einem Rutsch als Ganzes ausführen zu lassen. Das könnte in der Praxis einem Regressionstest entsprechen, dem wir unser SUT unterziehen wollen. Schließen Sie bitte den Browser, falls dieser aktuell läuft. Nun können Sie den Testfallsatz ”Web demo” markieren und ihn als Ganzes ausführen. Der Testlauf dauert eine knappe Minute. Dies liegt unter anderem an einer Verzögerung, die wir zur besseren Nachvollziehbarkeit eingebaut haben. Sie sehen in den Details des Testfallsatzknotens unter Standardwerte eine Variable ”delay”, die auf 500 ms definiert ist. Wenn Sie diesen Wert reduzieren, können Sie den Testlauf beschleunigen. Der Test endet mit den bekannten zwei Fehlern. Wenn Sie sich nun bitte das Protokoll ansehen, sehen Sie wie QF-Test den Test abarbeitet. Abbildung 10.17: Das Protokoll des gesamten Testfallsatzes ”Web demo”. Hier sieht man auch noch einmal die bereits erwähnte Eigenschaft des Testfallsatzknotens, dass vor jedem darin enthaltenen Test jeweils die Vorbereitungssequenz und da- 10.9. Reportgenerierung 143 nach jeweils die Aufräumsequenz abgearbeitet wird. Dadurch wird immer ein sauberer Ausgangszustand sichergestellt. 10.9 Reportgenerierung Im Qualitätssicherungsprozess ist es wichtig, Testergebnisse zu dokumentieren und auch zu archivieren. QF-Test bietet die Möglichkeit, aus Protokollen Testreports zu generieren. Wir wollen dies für das gerade aufgezeichnete Protokoll beispielhaft durchführen. Die Reportgenerierung kann im Protokollfenster über Datei→XML/HTML Report erstellen... angestoßen werden. Es erscheint ein Dialog zur weiteren Auswahl möglicher Parameter: Abbildung 10.18: Auswahldialog für die Reportgenerierung. Im ersten Feld können Sie den Dateinamen des Reports festlegen. QF-Test bietet zwei Arten von Reports - einen einfachen HTML Report und einen XML Report. Die XML 10.9. Reportgenerierung 144 Form kann der Anwender als Grundlage verwenden und sie mit Hilfe selbst geschriebener XSLT Stylesheets in einen beliebigen eigenen Report transformieren. Es gibt weitere Optionen, um die Behandlung von HTML und Doctags in Kommentarfeldern und das Anzeigen des Reports nach der Generierung in einem Browser zu steuern. Sie können die Felder einfach unverändert belassen. Weitere Details finden Sie bei Bedarf im Kapitel Reports und Testdokumentation des Anwenderhandbuchs. Wir wollen uns nun einen einfachen HTML Report zu unserem letzten Testlauf erzeugen lassen. Bestätigen Sie bitte den Dialog zur Reportgenerierung (nach einem eventuellen Anpassen der Optionen) mit ”OK”. Anschließend sollte sich automatisch Ihr Browser mit einem Ergebnis äquivalent zum folgenden Bild öffnen: Abbildung 10.19: Ein HTML Report. Der Testbericht beginnt mit einer Zusammenfassung, mit allgemeinen Systeminformationen im linken Bereich, einer Legende mit der Bedeutung der verwendeten Symbole rechts und dem Gesamtergebnis darunter. In unserem Fall sind es die bekannten zwei 10.9. Reportgenerierung 145 Fehler. Auf die Zusammenfassung folgt eine Fehlerübersicht, welche alle Fehler auflistet, inklusive Ort des Auftretens (den Testfall) und beschreibender Fehlermeldung. Teil drei bildet eine Übersicht der Testfallsätze, die hier nur den ”Web demo” Testfallsatz enthält, da unsere Testsuite nur diesen enthält. Zum Schluss werden alle Testfälle des ”Web demo” Testfallsatzes mit den zugehörigen Details, wie Beschreibung, Ergebnis und Laufzeit, aufgelistet. Die Reporterstellung in QF-Test ist ein praktisches Hilfsmittel, um einen Überblick über einen Testlauf zu gewinnen und ein Dokument zu Präsentations- und Archivierungszwecken zu erstellen. Kapitel 11 Erstellen einer eigenen Testsuite [45-60 Min] 11.1 Einführung Dieses Kapitel wird Sie durch die Schritte führen, die notwendig sind, um Ihre erste eigene Testsuite zu erstellen: • Starten des SUT aus QF-Test heraus. • Aufnehmen einiger Aktionen und Organisieren der Testsuite. • Erstellen eines Tests, welcher eine echte Funktionalität im SUT überprüft. 11.2 Starten der Anwendung Öffnen Sie bitte eine neue, leere Testsuite mittels Datei→Neue Suite... . Bitte beachten Sie, dass die ”alte” Testsuite in einem getrennten Fenster geöffnet bleibt. Stellen Sie bitte sicher, dass die Detailansicht aktiv ist ( Ansicht→Details anzeigen ). In der linken Ebene des zweigeteilten Bildschirms sehen Sie den Baum, welcher die Testsuite repräsentiert. Für den dort gerade ausgewählten Knoten werden auf der rechten Seite die Attribute im Detail angezeigt. Zu Beginn muss die zu testende Applikation (engl. System under Test oder SUT) aus QF-Test heraus gestartet werden. In unserem Fall ist dies der Browser mit der ”Web demo”, die wir bereits aus dem vorigen Kapitel kennen. Wir werden den SchnellstartAssistenten benutzen, um eine entsprechende Startsequenz zu erzeugen. 11.2. Starten der Anwendung 147 Öffnen Sie bitte den Schnellstart-Assistenten über das Extras Menü. Dieser sollte Sie entsprechend dem folgendem Bild begrüßen. Nach einem kurzen Hallo drücken Sie bitte den ”Weiter” Knopf. Abbildung 11.1: Der Schnellstart-Assistent. Hier kann der Typ der zu testenden Applikation ausgewählt werden. Selektieren Sie bitte ”Eine Webseite in einem Browser” und gehen Sie weiter. 11.2. Starten der Anwendung 148 Abbildung 11.2: Auswählen des SUT Typs. Nun werden Sie nach der URL der zu testenden Webseite gefragt, welches die ”Web demo” Seite sein wird. Der einfachste Weg diese auszuwählen, ist mithilfe des Knopfes den Dateibrowser zu öffnen und damit zum versionsspezifischen qftest-x.y.z Verzeichnis zu navigieren, dann weiter zu .../doc/tutorial/web/de, wo Sie dann die Datei index.html auswählen können. Anschließend gehen Sie bitte weiter zum nächsten Schritt im Assistenten. 11.2. Starten der Anwendung 149 Abbildung 11.3: Angabe der URL. Der nächste Schritt ermöglicht die Auswahl eines AJAX Toolkits auf dem die WebAnwendung basiert. Obwohl unser Demo keines der genannten Toolkits nutzt, können Sie einfach die empfohlene Autoerkennung aktiv lassen und weitergehen. 11.2. Starten der Anwendung 150 Abbildung 11.4: AJAX Toolkit. Nun ist es Zeit, den Browser fest zu legen. Bei Windows ist dies sehr wahrscheinlich der Internet Explorer, welcher bereits vorausgewählt ist und den wir auch für unseren ersten eigenen Test benutzen wollen. Unter Linux wählen Sie sinnvollerweise Firefox. 11.2. Starten der Anwendung 151 Abbildung 11.5: Auswahl des Browsers. An dieser Stelle hat man die Möglichkeit einen speziellen Kompatibiltätsmodus für den Internet Explorer auszuwählen, falls die zu testende Seite eine spezielle IE Version benötigt. Da dies in unserem Fall nicht erforderlich ist, können wir einfach auf ”Weiter” drücken. (Wenn Sie Firefox ausgewählt hatten, sehen Sie an diese Stelle eine andere Option und müssen das Installationsverzeichnis des Firefox Browsers angeben, den Sie zum Testen nutzen möchten.) 11.2. Starten der Anwendung 152 Abbildung 11.6: Internet Explorer compatibility mode. Der nächste Schritt bietet die Möglichkeit ein definiertes Java Programm für die Ausführung des Browser-Wrapper Prozesses anzugeben. Dies kann nötig sein, wenn Sie mehrere Java Version auf Ihrem Rechner installiert haben (insbesondere 32bit und 64bit) oder wenn Java Applets involviert sind. In den meisten Fällen sollte Sie mit dem vorgegebenen Wert weitergehen können. 11.2. Starten der Anwendung 153 Abbildung 11.7: Java Programm für das Starten des Browser Wrappers. Dieser Schritt bietet die Möglichkeit für einige Grundeinstellungen des Browsers. Sie können einfach die vorgeschlagenen Einstellungen beibehalten und fortfahren. 11.2. Starten der Anwendung 154 Abbildung 11.8: Die Browser-Einstellungen. Da wir nur mit einem Browser-Fenster arbeiten möchten, können Sie auch beim nächsten Schritt ohne Änderungen weitergehen. 11.2. Starten der Anwendung 155 Abbildung 11.9: Name für Browser-Fenster. Fast haben wir es geschafft. Bleibt noch die Vergabe eines Namens als Referenz für unseren Client. Wir wollen ihn einfach ”web” nennen. Das Auswahlkästchen auf der Seite lassen Sie bitte unangetastet leer und drücken bitte auf ”Weiter”. 11.2. Starten der Anwendung 156 Abbildung 11.10: Name des Clients. Zu guter Letzt gibt es einige Informationen was wir zu erwarten haben, wenn der Assistent nun seine Aufgabe, eine Startsequenz zu erzeugen, abschließt und wo es Hilfe gibt im Fall von Problemen. Deaktivieren Sie bitte noch die ”Automatisch starten” Option, da wir zuerst einen Blick auf die erzeugte Startsequenz werfen wollen. Nun drücken Sie bitte den ”Fertig” Knopf. 11.2. Starten der Anwendung 157 Abbildung 11.11: Abschließende Informationen. Die generierte Startsequenz erscheint in den ”Extrasequenzen” und enthält vier Hauptschritte: • Globale Variablen setzen • Browser ohne Fenster starten • Einstellungen für Browser setzen • Browser-Fenster mit URL öffnen Auf den ersten Blick mag dies ein wenig umständlich erscheinen, hat seine Begründung aber in einer einfachen Anpassbarkeit für spezielle spätere Anforderungen. Das Ausklappen der vier Sequenzen zeigt die Detail der einzelnen Schritte. 11.2. Starten der Anwendung 158 Abbildung 11.12: Generierte Startsequenz. • Der erste Schritt enthält drei ”Variable setzen” Knoten, die globale Variablen definieren: ”client”, der Bezeichner über den der Client angesprochen wird, den zu verwendenden Browsertyp ”browser” und ”mozhome”, das Installationsverzeichnis für, auf Mozilla basierende Browser. Für den Internet Explorer ist letztere Variable nicht erforderlich und deshalb in unserem Beispiel leer. • Schritt zwei startet den Browser-Prozess, jedoch ohne ein Browser-Fenster zu öffnen. Es folgt ein Warteschritt, um sicherzustellen, dass der Prozess läuft bevor es weitergeht. • Im nächsten Schritt werden die Browsereinstellungen gesetzt. Dies geschieht mit dem Aufruf der ”doStartupSettings” Prozedur aus der Standardbibliothek qfs.qft. Zusätzlich wird der Resolver für die Ajax Autoerkennung aktiviert. • Und im finalen Schritt wird das Browser-Fenster mit der angegebenen URL geöffnet, gefolgt von einem weiteren Warteschritt, der das vollständige Laden des Dokumentes sicher stellt. Sie können einen Blick auf die Details der Knoten werfen und werden im wesentlichen die Werte, die Sie während der einzelnen Schritte im Assistenten eingegeben haben, den entsprechenden Knotenattributen zugewiesen finden. Nun wollen wir die Sache in Aktion sehen. Stellen Sie bitte sicher, dass der Knoten Knopf oder betätigen einfach die ”Vorbereitung” ausgewählt ist und drücken Sie den Zeilenvorschub-Taste Return . Nach einigen Sekunden sollte das Browser-Fenster erscheinen und die Webdemo-Seite (133) anzeigen, äquivalent Abbildung 10.5 aus dem vorigen Kapitel. 11.3. 11.3 Hinzufügen einer Mausklick Sequenz 159 Hinzufügen einer Mausklick Sequenz Wir werden nun einen recht einfachen Test in Form einer Mausklick Sequenz hinzufügen. • Als Ausgangsposition gehen Sie bitte auf die Seite ”Willkommen”. • In QF-Test drücken Sie nun bitte den ”Aufnahme” Knopf und wechseln Sie zum Browser-Fenster. Von jetzt ab wird jede Maus- oder Tastaturaktion aufgenommen. • Wählen Sie nun die Seite ”Optionsfelder und Auswahlkästchen” aus (ebenfalls be(141) kannt aus dem letzten Kapitel Abbildung 10.15 ) und führen dort einige Aktionen durch und schließen diese mit einem Druck auf den ”submit” Knopf ab. • Zum Schluss wechseln Sie zurück zum QF-Test Fenster und drücken Sie dort den Knopf. Sie finden die neu aufgenommene Sequenz unter dem ”Extrasequenzen” Knoten, wie im folgenden Bild dargestellt. Abbildung 11.13: Der Baum nach Aufnahme der Mausklick Sequenz. Als Name wird standardmäßig Datum und Zeit der Erstellung verwendet. Dieser kann anschließend beliebig verändert werden. In der Sequenz gibt es neben den ”Mausklick” Knoten auch zwei Knoten ”Warten auf Laden des Dokuments”. Diese erzeugt QF-Test automatisch dann, wenn ein neues Dokument geladen wird. In unserem Fall beim initialen Wechsel auf die ”Optionsfelder und Auswahlkästchen” Seite und nach Drücken des ”submit” Knopfs, welcher auch einen Neuaufbau bewirkt. Wir wollen die neu erzeugte Sequenz als Überprüfung gleich wieder abspielen. Dabei dürfen wir nicht vergessen auf die ”Willkommen” Seite zu wechseln, denn das war ja die Ausgangsposition der Aufnahme. Anschließend markieren wir den Sequenzknoten und drücken auf . Der Ablauf der Mausklick Sequenz im SUT sollte sich nun wiederholen. Bevor wir einen etwas komplexeren Test erstellen, wollen wir aus dem Inhalt unserer ”Extrasequenzen” eine richtige Testsuite strukturieren. 11.4. 11.4 Strukturieren einer Testsuite 160 Strukturieren einer Testsuite Bisher haben wir in den ”Extrasequenzen” gearbeitet, die eine Art Spielwiese zum Ausprobieren darstellen. Nun wollen wir eine richtige Testsuite aufbauen. Als erstes selektieren wir den Knoten ”Testfallsatz” und ändern seinen Namen z.B. in ”Webdemo”. Anschließend expandieren Sie den Knoten und ändern den Namen des enthaltenen Testfalls z.B. auf ”Clickstream”. Nun muss die Vorbereitungssequenz aus den ”Extrasequenzen” in den Testfallsatz Knoten verschoben werden und zwar an die erste Stelle, d.h. vor den Testfall ”Clickstream”. Dies kann mit Hilfe des Kontextmenüs (rechte Maustaste Ausschneiden/Einfügen) oder der Tastenkombination Strg-X und Strg-V erreicht werden aber auch durch Ziehen mit der Maus (Drag&Drop). Hinweis Bei Drag&Drop kann der Zielknoten aufgeklappt werden, in dem man den Mauszeiger über dem ”+” links vom Zielknoten verweilen lässt. Nun ist die aufgenommene Clickstream-Sequenz an der Reihe, um aus den ”Extrasequenzen” geholt und in den Testfall ”Clickstream” abgelegt zu werden. Falls die Sequenz noch den Zeitstempel als Namen hat, können Sie ihn auch in etwas Sinnvolleres wandeln. Zum Schluss erzeugen wir eine ”Aufräumen” Sequenz, um den Browser zu beenden. Sie besteht aus zwei Schritten: Einer, den Client zu beenden und ein zweiter, um sicher zu stellen, dass er auch wirklich terminiert wurde. Führen Sie bitte selbständig diese kleine Aufgabe durch. Wenn Sie fertig sind, werfen Sie zum Vergleich bitte einen Blick auf die nachfolgende Grafik. 11.5. Überprüfen eines Textfeldes 161 Abbildung 11.14: Der Baum nach der Neustrukturierung. Damit haben wir die wichtigsten Schritte zur Strukturierung unserer Testsuite abgeschlossen. Im folgenden Abschnitt werden wir einen ”Check” aufnehmen, um den Inhalt eines Textfeldes zu überprüfen. 11.5 Überprüfen eines Textfeldes Wir wollen nun einen unwesentlich komplexeren Test erstellen, in dem wir ein Formular ausfüllen und den Ergebnisstring überprüfen. • Wenn der Browser nicht läuft, so starten Sie ihn bitte durch Ausführung der Vorbereitungssequenz. Ansonsten wechseln Sie auf die ”Willkommen” Seite, um einen sauberen Ausgangszustand zu haben. Drücken Sie nun in QF-Test den ”Aufnahme” Knopf und wechseln zum Browser-Fenster. • Wählen Sie die Seite ”Texteingabe” über die Menüzeile. Wir kennen Sie bereits (135) von Kapitel Abschnitt 10.5 . • Nun füllen Sie bitte das Formular mit einigen Daten aus und drücken abschließend den ”submit” Knopf. Ein String, welcher eine Zusammenfassung der eingegebenen Informationen darstellt, erscheint im Textbereich am Ende der Seite. 11.5. Überprüfen eines Textfeldes 162 • Wir wollen einen Check für diesen Ergebnisstring aufzeichnen. Hierfür aktivieren Sie bitte den ”Check aufnehmen” Knopf in QF-Test und wechseln wieder zum Browser. Wenn Sie dort den Mauszeiger über Komponenten bewegen, werden diese durch einen Rahmen hervorgehoben. Um den Check aufzuzeichnen, manövrieren Sie bitte die Maus zu besagtem Textbereich und betätigen Sie die rechte Maustaste. Das Menü beinhaltet verschiedene Arten von Checks, beginnend mit ”Text”. Die folgende Abbildung zeigt die Situation: Abbildung 11.15: Aufnahme eines Text Checks. • Wählen Sie bitte den ”Text” Check aus und beenden Sie danach die Aufnahme mit . Tipp: Anstatt für die Aktivierung des Checkmodus zurück in die Testsuite zu springen, um den Knopf zu drücken, können Sie auch einfach im SUT bleiben und 11.5. Überprüfen eines Textfeldes 163 die Taste F12 verwenden. Sie aktiviert/deaktiviert den Modus zum Aufnehmen von Checks. Sie sollten nun die Kenntnisse besitzen, um die aufgenommene Sequenz in einem Testfall zu organisieren. Anschließend können Sie Ihr Ergebnis mit unserer folgenden Lösung vergleichen. Hierbei haben wir zusätzlich Sequenzen in ”Testschritt” Knoten konvertiert, womit sie genauer spezifiziert sind und auch im Report sichtbar werden. Abbildung 11.16: Der Baum nach Aufnahme und Organisieren des ”Text check” Knotens. Hinweis Knoten konvertieren kann man sehr einfach über den Menüpunkt Operationen Knoten konvertieren in oder über das Kontextmenü des Knotens. Lassen Sie uns einen ersten richtigen Testlauf mit unserer neuen Suite durchführen. Beenden Sie dazu bitte den Browser und markieren den Wurzel-Testknoten. Führen Sie diesen durch Drücken von ”Wiedergabe” oder der Return Taste aus. Verläuft alles nach Plan? Das Ergebnis des Testlaufs wird im ”Protokoll” festgehalten. Um dieses anzuschauen, können wir direkt den Button ”Protokoll anzeigen” nutzen oder wir wählen im Menü Wiedergabe→1. ... oder aber benutzen die Tastenkombination Strg-L . 11.5. Überprüfen eines Textfeldes 164 Abbildung 11.17: Der Protokollbaum zum eigenen Test. Im Protokoll wird nochmal deutlich, dass die Knoten ”Vorbereitung” und ”Aufräumen” vor bzw. nach jedem Testfall ausgeführt werden, um für definierte Zustände zu sorgen. Hinweis Das Starten und Beenden der zu testenden Anwendung vor und nach jedem Testfall ist zwar ein sicherer Weg zum Herstellen sauberer Ausgangsbedingungen, jedoch auch ein zeitaufwendiger. In der Regel wird man versuchen das SUT nur einmal zu starten und durch andere Methoden einen definierten Ausgangszustand sicherzustellen. In diesem Testlauf traten keine Fehler oder Exceptions auf. Aber Sie sehen gelbe Rahmen um einige Knoten im Protokollbaum, welche auf Warnungen hinweisen. Im Webdemo werden sie durch Komponenten hervorgerufen, die keine Namen zugewiesen haben. Wir möchten an dieser Stelle nicht weiter auf diese Warnungen eingehen, aber Sie finden ausführliche Informationen zur Wichtigkeit von Komponentennamen im Handbuch. Beim Schließen des Protokolls wird gefragt, ob Sie speichern möchten, da es nur so lange verfügbar ist, bis QF-Test beendet wird. 11.5. Überprüfen eines Textfeldes 165 Wir werden nun einen Fehler in Knoten ”Check Text” provozieren. Selektieren Sie den ”Text Check” Knoten, um die Detailansicht zu öffnen: Abbildung 11.18: Ausschnitt der Detailansicht des Knotens ”Check Text”. Im ”Text” Feld lässt sich ablesen, welchen Wert QF-Test in diesem Check erwartet. Um einen Fehler zu verursachen, ändern Sie diesen Text in beliebiger Weise ab. Bestätigen Sie anschließend Ihre Eingabe mit OK und führen den Test erneut aus. Ein Dialog mit dem Hinweis erscheint, dass, wie erwartet, ein Fehler aufgetreten ist. Wenn Sie nun das neue Protokoll öffnen, sehen Sie ein rotes Quadrat um den Knoten ”Check Text”, welches anzeigt, dass unterhalb dieses Knotens ein Fehler aufgetreten ist. Benützen Sie im Menü Bearbeiten→Nächsten Fehler finden oder die Tastenkom bination Strg-N , dann sehen Sie den von QF-Test erwarteten Text und was im Testlauf gefunden wurde. Um den ”Check” Knoten wieder zu korrigieren, können Sie sich einer hilfreichen Funktion in QF-Test bedienen. Klicken Sie mit der rechen Maustaste auf den Knoten im Protokoll, der die Abweichung angezeigt hat und wählen Sie aus dem erscheinenden Kontextmenü ”Check Knoten mit erhaltenen Daten aktualisieren”. Uff, die erste eigene Testsuite ist fertig. Vielleicht möchten Sie diese zum Abschluss speichern. Kapitel 12 Weitere Beispiele [5 Min] Der Teil über Webtesten in diesem Tutorial enthält nur die ersten Schritte für den Einstieg. Da jedoch die Konzepte identisch sind, sollten Sie unbedingt auch den parallelen Java-Teil nutzen, um weitere Möglichkeiten und Features von QF-Test kennen zu lernen. Außerdem finden Sie neben anderen Beispielen eine erweiterte Testsuite webdemo2.qft für das in diesem Tutorialteil verwendete Webdemo im Verzeichnis qftest-4.0.6/demo/web/. Darin werden fortgeschrittene Techniken wie Abhängigkeiten, Datentreiber und sogar Resolver genutzt. Auch wird gezeigt, wie verschiedene Browser für Tests auf unterschiedlichen Betriebssystemen verwendet werden können. Teil III Weiterführende Features von QF-Test Kapitel 13 Einführung [5 Min] Dieser Abschnitt des Tutorials beschreibt Features von QF-Test, welche für fortgeschrittene Benutzer interessant sind. Die folgenden Kapitel verwenden die JCarConfigurator Demoapplikation. Der JCarConfigurator ist in Java/Swing implementiert, die Konzepte allerdings sind für jede unterstützte Technologie anwendbar. Für jedes Kapitel gibt es auch spezielle Testsuiten, damit Sie die Themen jedes Kapitels einzeln nachverfolgen können. Diese Dateien finden Sie unter qftest-4.0.6/doc/tutorial/advanced-demos/de. Kapitel 14 Die Demoapplikation [5 Min] Das SUT für dieses Tutorial ist der JCarConfigurator. Mit dieser Software kann man Preise von Autos kalkulieren. Hier ist eine Liste der von ihr unterstützten Features: • Ein Automodell auswählen und den Basispreis kalkulieren. • Spezielle Zubehörteile einem Modell zuordnen. • Mehrere Zubehörteile können auch zu einem Sondermodell zusammengefasst werden. • Einen Rabatt gewähren. • Ein neues Automodell anlegen. • Ein neues Zubehörteil anlegen. • Ein neues Sondermodell anlegen. Sie können den JCarConfigurator entweder qftest-4.0.6/demo/carconfig/run_car.bat auf Windows qftest-4.0.6/demo/carconfig/run_car.sh auf Unix starten. Hinweis mittels oder Falls Sie den JCarConfigurator auf Englisch starten möchten, müssten Sie den Parameter en beim Skriptaufruf mitgeben. Hier sehen Sie ein Bildschirmabbild des Hauptfensters: Die Demoapplikation [5 Min] 170 Abbildung 14.1: Das Hauptfenster vom JCarConfigurator Hinweis Der JCarConfigurator ist eine Java/Swing Anwendung. Die Konzepte um diese Applikation zu testen sind allerdings die selben wie bei Applikationen, die in anderen, von QF-Test unterstützten, Technologien benötigt werden. Kapitel 15 Datengetriebenes Testen: Einen Test-case mit unterschiedlichen Testdatensätzen starten [30-45 Min] Dieses Kapitel erklärt, wie man datengetriebenes Testen mit QF-Test verwirklichen kann. Sie finden unter qftest-4.0.6/doc/tutorial/advanced-demos/de/datadrivenTesting.qft die hier gezeigten Testfälle. 15.1 Situation Die Anwender des JCarConfigurator können unterschiedliche Rabattstufen gewähren. Der Testdesigner hat drei Rabattstufen definiert, die getestet werden sollen. Diese Rabattstufen sind 0%, 10% und 15%. Der Ablauf, um einen Rabatt zu gewähren, ist für jede dieser drei Rabattstufen derselbe. Daher können wir denselben Testfall benutzen, um diese zu testen. Der einzige Unterschied ist der eingegebene Rabattsatz und der zu prüfende Preis. Wir sollten denselben Testfall für jede Rabattstufe benutzen, um Seiteneffekte zu vermeiden, die bei unterschiedlichen Implementierungen der Testfälle auftreten können. Darüberhinaus sparen wir uns auch den Implementierungsaufwand zum Erstellen mehrerer Testfälle. Der logische Testfall, d.h. die Schritte des Testfalles, sehen folgendermaßen aus: 1. Starten des SUTs. 2. Ein Modell auswählen. 15.2. Die traditionelle Methode für datengetriebenes Testen 172 3. Den Rabatt eingeben. 4. Prüfen, ob der Rabatt für die Preiskalkulation herangezogen wurde. 5. Das SUT stoppen. Die folgenden Abschnitte zeigen nun die Implementierung dieses Szenarios. 15.2 Die traditionelle Methode für datengetriebenes Testen In QF-Test steht ein Testfall für einen Testablauf zusammen mit einem speziellen Testdatensatz. Wenn man zwei Testdatensätze testen möchte, so muss man zwei Testfälle erstellen. Diese Testfälle können auch in einem Testfallsatz zusammengefasst werden. Bei der konventionellen Lösung implementiert man also einen Testfall pro Rabattstufe. Das sieht dann so aus: Abbildung 15.1: Konventionelle Methode für datengetriebenes Testen Wir sehen für jede der drei Rabattstufen genau einen Testfall Knoten. Diese drei Knoten sind in einem Testfallsatz zusammengefasst. Der Testfallsatz Knoten beinhaltet auch die Vorbereitung und die Aufräumen Knoten, welche das SUT vor jedem Testfall starten und nach jedem Testfall stoppen. Dies geschieht, um sicherzustellen, dass die Vorbedingungen jedes einzelnen Testfalles dieselben sind. Wenn Sie die SUT nicht nach jedem Testfall neu starten wollen, dann können Sie die drei Testfälle in einem weiteren Testfallsatz zusammenfassen, wie Sie hier sehen können: Abbildung 15.2: Konventionelle Methode mit einem verschachtelten Testfallsatz 15.3. Datentreiberkonzept 173 Das Kapitel Abhängigkeiten: Automatisches Sicherstellen der korrekten (181) Vorbedingungen jedes Testfalles [60 Min] zeigt Ihnen eine elegantere und effizientere Art, Vor- und Nachbedingungen von Testfällen zu organisieren. Wie Sie sich sicher vorstellen können, wird es mit dieser Methode ziemlich mühsam sein, die Testdaten zu verwalten. Insbesondere, wenn Sie eine neue Rabattstufe anlegen oder eine Stufe wegfällt. Ein weiterer Nachteil dieses Ansatzes ist, dass die Testdaten in QF-Test gehalten werden. (173) Das nächste Kapitel Datentreiberkonzept zeigt Ihnen nun, wie Testsuiten organisiert werden können, in denen nur ein Testfall implementiert wird und die Testdaten unabhängig vom Testfall abgelegt werden. 15.3 Datentreiberkonzept Wenn man nun einen Testfall starten möchte, der mehrere Testdatensätze verwendet, muss man zuerst die Testdatensätze in einer Datenquelle definieren. Diese Datenquelle muss innerhalb eines Datentreiber Knotens definiert werden. QF-Test bietet Standardverknüpfungen für Datenbanktabellen, CSV Dateien, Excel Dateien und für innerhalb von QF-Test definierte Datentabellen an. Die QF-Test Datentabelle definiert die Testdaten an einer Stelle der Testsuite. Wir werden diese Datenquelle für unser folgendes Beispiel nutzen. Jede andere Datenquellenart, z.B. XML Dateien, kann mit einem selbstimplementierten Skript angebunden werden. Fügen Sie zuerst einen neuen Testfallsatz in die Testsuite ein. Sie können den Namen frei wählen. Ein Datentreiber Knoten kann in einen Testfallsatz mittels Rechtsklick und Auswahl von Knoten einfügen→Datentreiber→Datentreiber eingefügt werden. Sie müssen nur noch einen Namen für diesen Knoten definieren. Die eigentliche Testdatenquelle kann als Kindknoten des Datentreiber Knotens eingefügt werden. In unserem Fall werden wir eine ’Datentabelle’ mittels Rechtsklick und Auswahl von Knoten einfügen→Datentreiber→Datentabelle einfügen. Sie sollten nun diesen Dialog erhalten: 15.3. Datentreiberkonzept 174 Abbildung 15.3: Dialog für eine Datentabelle Zuerst müssen wir einen Namen für diese Datenquelle spezifizieren. Wir sollten auch eine ’Zählervariable’ definieren. Die Zählervariable beinhaltet den Index des aktuell verwendeten Datensatzes während der Testausführung. Der nächste Schritt ist die Definition der Testdaten. Dafür klicken Sie auf den Knopf ’Spalte einfügen’. Das ist der erste Knopf im ’Daten’ Bereich. Dann müssen Sie einen Namen für diese Spalten definieren. Setzen Sie den Namen auf ’rabatt’. Danach drücken Sie auf ’OK’ und die Spalte sollte eingefügt worden sein. Diese Spalte wird später der Variablenname in den Tests sein. Nun klicken Sie auf den ’Zeile einfügen’ Knopf, um eine neue Zeile einzufügen. Jede Zeile wird für einen eigenen Testdatensatz stehen, d.h., dass wir jetzt drei Zeilen einfügen müssen. Die erste Zeile soll 0%, die zweite 10% und die dritte 15% beinhalten. Die Tabelle sollte nun so aussehen: 15.3. Datentreiberkonzept 175 Abbildung 15.4: Die gefüllte Datentabelle Nun kommen wir zur eigentlichen Implementierung des Testfalles. Dafür müssen wir nur einen Testfall zum Testfallsatz hinzufügen. Hinweis Wenn sie einen Testfall zu einem Testfallsatz hinzufügen wollen, dann müssen Sie auf den geschlossenen Datentreiber klicken, um den Testfall einzufügen. Der Testfall wird die Prozeduraufrufe für die benötigten Testschritte beinhalten. Sie können auch die Vorbereitung und die Aufräumen Knoten aus dem vorigen Testfallsatz in den neuen Testfallsatz kopieren. Der gesamte Testfallsatz sollte nun so ausschauen: Abbildung 15.5: Testfallsatz mit Datentreiber Jetzt müssen wir noch die Variable ’rabatt’, welche in der Datentabelle definiert wurde, verwenden. Wir sollten diese Variable als Parameter für den ’setzeRabatt’ Prozedurauf- 15.3. Datentreiberkonzept 176 ruf hinzufügen. Wenn wir das gemacht haben, sollte unser Test so aussehen: Abbildung 15.6: Der $(rabatt) Parameter Nun sind wir bereit den Testfallsatz zu starten. Nach der Ausführung der Tests sollten wir mindestens zwei Fehler bekommen. Diese Fehler kommen daher, dass das ’Endpreis’ Textfeld natürlich unterschiedliche Werte enthält wir aber immer denselben Wert prüfen. In unserem Fall sollte also der erwartete Wert für das ’Endpreis’ Textfeld als zweite Spalte in die ’Datentabelle’ eingefügt werden. 15.3. Datentreiberkonzept 177 Abbildung 15.7: Vollständige Datentabelle Ein weiterer Nachteil ist, dass wir im HTML Report und im Protokoll immer denselben Testfallnamen sehen. Um dies zu vermeiden, sollten wir die Eigenschaft ’Name für Protokoll und Report’ des Testfall Knotens editieren. In dieser Eigenschaft sollten wir zumindest eine datensatz-spezifische Variable verwenden, z.B. ’rabatt’ in unserem Fall. Lassen Sie uns dieses Attribut also auf ’Rabattstufe: $(rabatt)’ setzen. 15.3. Datentreiberkonzept 178 Abbildung 15.8: Name für Protokoll und Report Eigenschaft Wenn wir den Test nun ausführen, sollten wir keine Fehler mehr erhalten und im Protokoll sowie im HTML Report sollte jeder Testfall einen eigenen Namen haben. Das erzeugte Protokoll sollte folgendermaßen aussehen: 15.4. Zusammenfassung 179 Abbildung 15.9: Protokoll mit unterschiedlichen Namen für Testfälle Wenn Sie nur einen Testfall mit einem Datensatz ausführen möchten, ohne den gesamten Testfallsatz auszuführen, dann sollten Sie Defaultwerte als globale Variablen des Testsuite Knoten definieren. Hinweis Wenn der Name der Variable im Datentreiber der selbe ist, wie der des Prozedurparameters, dann können Sie die Variablendefinition beim Prozeduraufruf weglassen. Das kann gemacht werden, weil die Variablen des Datentreiber Knotens auch auf den Variablenstack von QF-Test gelegt werden und so jeder Schritt innerhalb des Testfall Knotens auf diese Variablen zugreifen kann. Sie können eine solche Implementierung im Testfallsatz ’Datengetriebener Test mit optimierten Prozeduraufrufen’ in der Demotestsuite qftest-4.0.6/doc/tutorial/advanced-demos/de/datadrivenTesting.qft sehen. In der Demotestsuite qftest-4.0.6/doc/tutorial/advanced-demos/de/datadrivenTesting.qft finden Sie auch einen Testfallsatz, der eine CSV Datei als Datenquelle nutzt. 15.4 Zusammenfassung Das Datentreiber Konzept von QF-Test ermöglicht es dem Benutzer, logische Testfälle zu erstellen und die Testdaten von der eigentlichen Testimplementierung separiert zu 15.4. Zusammenfassung 180 halten. Es ist auch möglich, verschachtelte Datentreiber Knoten in Testfälle zu verwenden. Dies kann realisiert werden, indem man einen Test Knoten zu einem Testfall hinzufügt. Der Test Knoten kann dann den Datentreiber beinhalten. Eine detaillierte Beschreibung von datengetriebenem Testen finden Sie im Handbuch im Kapitel Datengetriebenes Testen. Die mitgelieferte Testsuite qftest-4.0.6/doc/tutorial/datadriver.qft enthält weitere Beispiele für den Einsatz von Datentreibern. Kapitel 16 Abhängigkeiten: Automatisches Sicherstellen der korrekten Vorbedingungen jedes Testfalles [60 Min] Dieses Kapitel erklärt das Abhängigkeiten Konzept von QF-Test. Dieses Konzept ist für die Erstellung robuster Testfälle sowie für das Recovery Management sehr wichtig. Abhängigkeiten wurden eingeführt, um sicherzustellen, dass jeder Testfall mit erfüllten Vorbedingungen laufen kann. Die Beispiele aus diesem Kapitel finden Sie in der Testsuite qftest-4.0.6/doc/tutorial/advanced-demos/de/dependencies.qft. Des weiteren gibt es noch eine zweite Testsuite qftest-4.0.6/doc/tutorial/advanced-demos/de/dependencies_work.qft, die Sie für die Erstellung der Beispiele verwenden können. 16.1 Einführung Bitte öffnen Sie die Testsuite qftest-4.0.6/doc/tutorial/advanced-demos/de/dependencies_work.qft und werfen Sie einen Blick auf den ersten Testfallsatz ’Rabattstufen Tests’. Dieser enthält drei Testfall Knoten und eine Vorbereitung, sowie einmal Aufräumen, um das SUT vor jedem Testfall zu starten bzw. zu stoppen. Das ist ein typisches Beispiel, wie Testsuiten in Projekten aussehen können. 16.1. Einführung 182 Abbildung 16.1: Erster Testfallsatz von dependencies_work.qft Angenommen, wir wollen nur einen speziellen Testfall starten, weil genau dieser einen Defekt verifiziert oder dieser beim letzten Lauf fehlerhaft war. Dafür müssten wir entweder den gesamten Testfallsatz ausführen oder dafür sorgen, dass alle Vorbedingungen erfüllt sind, d.h. die einzelnen Vorbereitung Knoten müssten manuell ausgeführt werden. Diese Situation passiert sehr häufig, ist allerdings nicht einfach aufzulösen mit den jetzt bekannten Mitteln. Für solche Fälle liefert QF-Test das Abhängigkeiten Konzept. Es erleichtert die Verwaltung von Vorbedingungen und erlaubt es einen Testfall einzeln zu starten. In diesem Fall wird QF-Test die Kontrolle über die Sicherstellung der Vorbedingungen übernehmen, also z.B. das SUT starten oder ein Fahrzeugmodell selektieren. Eine Abhängigkeit kann einen Vorbereitung, einen Aufräumen, einen Fehlerbehandlung und einen Catch Knoten beinhalten. Die Vorbereitung einer Abhängigkeit wird vor jedem Testfall ausgeführt, damit immer sichergestellt ist, dass die Vorbedingungen des jeweiligen Testfalles erfüllt sind. Das Sicherstellen der Vorbedingungen ist ein sehr wichtiger Aspekt für eine robuste und stabile Testausführung. Sie können sich eine Situation vorstellen, in der ein Testfall das SUT beendet und daher der darauffolgende Testfall das SUT wieder starten muss. Genau für diese Situationen liefert das Abhängigkeit Konzept eine stabile und attraktive Lösung. Der zweite Aspekt des Abhängigkeiten Konzeptes ist die Optimierung der Testausführung. Mit den bisherigen Mitteln mussten wir das SUT vor jedem Testfall starten und nach jedem Testfall stoppen. Dies ist für kleinere Applikationen wie dem JCarConfigurator auch kein Problem, aber stellen Sie sich das für eine große Applikation, wie eine Eclipse/RCP Anwendung oder ein ERP System, vor. Hier könnte dieses Vorgehen ziemlich ineffizient werden. Genau deshalb wird bei Abhängigkeiten die Aufräumen nur bei Bedarf ausgeführt. Ein weiterer Vorteil von Abhängigkeiten sind globale Fehlerbehandlung und Catch Knoten für die Implementierung von Recovery Management Schritten. Dieses Feature ist besonders dann wichtig, wenn Sie viele Testfälle hintereinander ausführen und ein fehlerhafter die Ausführung der darauffolgenden behindern kann, z.B. durch das Erscheinen eines modalen Fehlerdialoges wie ’OutOfMemoryException’. Zusammengefasst sind Abhängigkeiten: 1. eine Stelle, um Vorbedingungen eines Testfall zu definieren. 16.2. Sicherstellen von Vorbedingungen 183 2. sehr nützlich, um Testfälle unabhängiger voneinander zu gestalten. 3. ein besserer Ansatz, um Vorbereitung und Aufräumen Schritte zu implementieren. 4. eine Stelle, um Recoveryschritte im Fehlerfall bzw. beim Auftreten von Exceptions zu definieren. 5. eine Optimierungsmöglichkeit für die Testausführung. 6. wiederverwendbar, da sie im Prozeduren Bereich abgelegt werden können. Die folgenden Abschnitte zeigen, wie man Abhängigkeiten anlegt und benutzt. 16.2 Sicherstellen von Vorbedingungen Bitte öffnen Sie die Testsuite qftest-4.0.6/doc/tutorial/advanced-demos/de/dependencies_work.qft. Diese Datei enthält einen Testfallsatz ’Rabatt-Tests’ mit drei Testfälle und der herkömmlichen Implementierung von Vorbereitung und Aufräumen Knoten. Wir werden nun in diesen Testfallsatz eine Abhängigkeit einbauen. Abbildung 16.2: Erster Testfallsatz von dependencies_work.qft Zuerst müssen wir einen Abhängigkeit Knoten einfügen. Dies macht man mittels Rechtsklick auf den Testfallsatz und Auswahl von Knoten einfügen→Abhängigkeiten→Abhängigkeit . Geben Sie der Abhängigkeit einen Namen, z.B. ”SUT gestartet”. Der nächste Schritt ist das Verschieben der Vorbereitung und Aufräumen Sequenzen in diese Abhängigkeit. Hierfür müssen Sie den Abhängigkeit Knoten öffnen und die entsprechenden Knoten hineinschieben. Das können Sie entweder via Drag and Drop oder Rechtsklick Ausschneiden und Einfügen oder mittels Ctrl-X und Ctrl-V . Die Testsuite sollte nun so aussehen: 16.2. Sicherstellen von Vorbedingungen 184 Abbildung 16.3: Beispiel Testsuite mit der ersten Abhängigkeit Jetzt wollen wir die Abhängigkeit testen. Stoppen Sie bitte vorher alle laufenden SUTs. Dann selektieren Sie einen Testfall, z.B. ’Rabattstufe 10’ und starten diesen. Sie sollten nun sehen, dass der Testfall ausgeführt wurde und das SUT am Ende des Testlaufes nicht gestoppt wurde. Bitte öffnen Sie das Protokoll um nachzusehen, was genau passiert ist. Abbildung 16.4: Das Protokoll der Ausführung Wenn Sie im Protokoll den Testfall öffnen, dann sehen Sie einen ’Abhängigkeiten auflösen’ Knoten. Wenn Sie diesen öffnen, werden Sie zwei weitere Knoten sehen. Der letzte der beiden Knoten zeigt Ihnen, dass die Vorbereitung Sequenz ausgeführt wurde. Der erste Knoten wird im nächsten Beispiel erklärt. Bis jetzt haben wir gesehen, dass die Vorbereitung Sequenz automatisch vor dem Testfall ausgeführt wird. Jedoch wurde Aufräumen noch nicht ausgeführt. Wenn Sie jetzt einen weiteren Testfall starten, z.B. ’Rabattstufe 15’, dann bekommen wir eine ’DuplicateClientException’ am Beginn des Testlaufes. QF-Test wird den Testlauf unterbrechen und der Debugger erscheint. Bitte stoppen Sie den Debugger. Warum ist das passiert? Die Vorbereitung einer Abhängigkeit wird auf jeden Fall vor jedem Testfall ausgeführt. Dies geschieht um die Vorbedingungen jedes einzelnen Testfall’s sicherzustellen. Das 16.2. Sicherstellen von Vorbedingungen 185 Aufräumen einer Abhängigkeit wird nur bei Bedarf ausgeführt, d.h. nur dann, wenn die Schritte der Vorbereitung nicht mehr benötigt werden. In unserem Fall wurde das Aufräumen nicht ausgeführt, weil beide Testfälle dieselbe Abhängigkeit haben. Deshalb müssen wir die Implementierung der Vorbereitung ein wenig anpassen. Und zwar soll vorher geprüft werden, ob die entsprechende Vorbedingung bereits erfüllt wurde oder nicht. Falls nicht, dann müssen die Vorbedingungen hergestellt werden. In unserem Beispiel müssen wir prüfen, ob das SUT bereits gestartet wurde. Dies kann mittels eines Warten auf Client Knotens geschehen. Dieser Knoten prüft, ob bereits eine Verbindung zwischen dem SUT und QF-Test besteht. Sie müssen auch das Attribut ’Wartezeit’ auf ’0’ setzen, weil wir davon ausgehen, dass das SUT bereits läuft. Falls es nicht laufen sollte, müssen wir es ohnehin starten. Eine solche Anforderung kann mittels eines Try-Catch Konstruktes, wie im nächsten Abbild beschrieben, gelöst werden: Abbildung 16.5: Die neue Implementierung der Vorbereitung Sie könnten auch das Attribut ’Variable für Ergebnis’ des Warten auf Client Knotens benutzen und das Resultat dann in einer If Bedingung überprüfen. Jetzt sind wir bereit, um den Testfall ’Rabattstufe 15’ zu starten. Dieser Test sollte nun erfolgreich durchlaufen. Der nächste Schritt ist, den gesamten Testfallsatz mittels Klick auf ’Wiedergabe starten’ auszuführen. Alle drei Testfälle sollten erfolgreich durchgelaufen sein und das SUT sollte auch nicht zwischen den Ausführungen gestoppt worden sein. Wir haben also auch die Testausführung optimiert. Die Aufräumen wurde nicht ausgeführt, da alle drei Testfälle auf dieselbe Abhängigkeit verweisen. Somit sieht unsere Testumgebung auch mehr nach einer realen Umgebung aus, da die wenigsten Benutzer das SUT nach jeder Aktion neu starten werden. Das nächste Ziel ist, unsere Abhängigkeit für andere Testfallsätze unseres Projektes verfügbar zu machen. Hierfür müssen wir die Abhängigkeit in den Prozeduren Bereich verschieben. Danach müssen wir auf den Testfallsatz klicken und eine Bezug auf Abhängigkeit einfügen. Dies macht man mittels Rechtsklick und Auswahl von Der erscheinende Knoten einfügen→Abhängigkeiten→Bezug auf Abhängigkeit . Dialog sieht dann dem Prozeduraufruf Dialog ziemlich ähnlich. Wählen Sie die gerade verschobene Abhängigkeit aus. Die Testsuite sollte nun wie folgt aussehen: 16.2. Sicherstellen von Vorbedingungen 186 Abbildung 16.6: Die Testsuite mit Bezug auf Abhängigkeit Wir empfehlen alle Abhängigkeiten in ein separates Package ’abhängigkeiten’ zu schieben. Wenn Sie nun den Testfallsatz ausführen, wird bei der ersten Ausführung nach Verschieben der Abhängigkeit das SUT gestoppt und das SUT wiederum gestartet. Das passiert, weil die Abhängigkeit in den Prozeduren Bereich verschoben wurde und es deshalb eine andere Abhängigkeit ist als vorher. Werfen Sie nun einen Blick auf den zweiten Testfallsatz der Demotestsuite ’Rabatt-Tests mit Stoppen des SUT’. Der zweite Testfall ’Rabattstufe 10’ stoppt das SUT, jedoch benötigt der dritte Testfall ’Rabattstufe 15’ auch ein laufendes SUT. Wie wir in diesem Abschnitt gelernt haben, wird das Abhängigkeiten Konzept dafür Sorge tragen, dass das SUT vor dem dritten Testfall ausgeführt wird. Dieses Beispiel sollte noch einmal die Vorteile von Abhängigkeiten verdeutlichen. 16.3. Verschachtelte Abhängigkeiten 187 Abbildung 16.7: Sicherstellen der Vorbedingungen für Testfall ’Rabattstufe 15’ 16.3 Verschachtelte Abhängigkeiten Verwalten von Vorbedingungen kann ein durchaus komplexeres Thema werden, als dass wir nur Sicherstellen, ob das SUT gestartet wurde oder nicht. In vielen Projekten gibt es verschiedene Gruppen von Testfällen mit unterschiedlichen Vorbedingungen. Nehmen wir an, dass wir ein großes ERP System mit mehreren Perspektiven, wie ’Anbieter’ und ’Artikel’ testen möchten. Jeder Testfall für die ’Anbieter’ Perspektive bezieht sich darauf, dass die ’Anbieter’ Perspektive auch geöffnet ist. Genauso verhält es sich bei allen Tests für die ’Artikel’ Perspektive. Das Öffnen der jeweiligen Perspektive hängt wiederum vom eingeloggten Benutzer ab, und das Einloggen basiert auf einem gestarteten SUT. Sie sehen also, es gibt so etwas wie einen Baum von Vorbedingungen. QF-Test ermöglicht es dem Benutzer, solch verschachtelte Abhängigkeit Knoten zu er- 16.3. Verschachtelte Abhängigkeiten 188 stellen. Hierfür muss man Bezug auf Abhängigkeit Knoten zu einer Abhängigkeit hinzufügen. Wir werden nun ein kleines Beispiel mit zwei verschachtelten Abhängigkeiten für den JCarConfigurator bauen. Im JCarConfigurator können Sie den ’Fahrzeuge’ Dialog mittels der Menüaktion ’Einstellungen’ -> ’Fahrzeuge’ öffnen. Wir wollten jetzt Tests für diesen Dialog erstellen. Später werden wir auch Tests für den ’Zubehör’ Dialog erstellen, welcher auch über das Menü mittels ’Einstellungen’ -> ’Zubehör’ geöffnet werden kann. Zuerst definieren wir die Tests, welche wir erstellen wollen. Testfall 1: Anlegen des Modells ’test1’ mit Preis ’100’. • Starten des SUT, falls notwendig. • Fahrzeugdialog öffnen. • Name ’test1’ und Preis ’100’ setzen. • ’Neu’ klicken. • Den Dialog mittels ’OK’ schließen. • Den Fahrzeugdialog nochmal öffnen. • Das angelegte Modell ’test1’ selektieren. • Den Dialog mit ’Abbrechen’ schließen. • Das SUT stoppen, falls notwendig. Testfall 2: Anlegen des Modells ’test2’ mit Preis ’99999’. • Start des SUT, falls notwendig. • Fahrzeugdialog öffnen. • Name ’test2’ und Preis ’99999’ setzen. • ’Neu’ klicken. • Den Dialog mittels ’OK’ schließen. • Den Fahrzeugdialog nochmal öffnen. • Das angelegte Modell ’test2’ selektieren. • Den Dialog mit ’Abbrechen’ schließen. • Das SUT stoppen, falls notwendig. 16.3. Verschachtelte Abhängigkeiten 189 Testfall 3: Anlegen des Zubehöres ’testzubehör’ mit Preis ’12’. • Start des SUT, falls notwendig. • Zubehördialog öffnen. • Name ’testzubehör’ und Preis ’12’ setzen. • ’Neu’ klicken. • Den Dialog mittels ’OK’ schließen. • Den Zubehördialog nochmal öffnen. • Das angelegte Zubehörteil ’testzubehör’ selektieren. • Den Dialog mit ’Abbrechen’ schließen. • Das SUT stoppen, falls notwendig. Wenn wir uns nun die Testschritte der oben definierten Testfälle genauer anschauen, sehen wir, dass jeder Testfall ein laufendes SUT benötigt. Daher sollten wir eine Abhängigkeit ’SUT gestartet’ implementieren. Das Stoppen des SUT ist ein optionaler Schritt, der innerhalb des Aufräumen Knotens dieser Abhängigkeit implementiert werden kann. Diese Abhängigkeit haben wir schon im vorigen Beispiel erstellt und können diese also wiederverwenden. Der nächste Punkt ist, dass sowohl Testfall 1 wie auch Testfall 2 einen geöffneten Fahrzeugdialog benötigen. Da wir weitere Tests in diesem Bereich planen, sollten wir eine Abhängigkeit ’Fahrzeugdialog geöffnet’ erstellen. Diese sollte in der Vorbereitung das Öffnen des Dialoges und in der Aufräumen das Schließen mittels ’Abbrechen’ beinhalten. Wir können diesen Dialog nur dann öffnen, wenn das SUT bereits läuft, deshalb ist diese Abhängigkeit auch von der Abhängigkeit ’SUT gestartet’ abhängig. Die Implementierung der ’Fahrzeugdialog geöffnet’ Abhängigkeit sieht wie folgt aus: Abbildung 16.8: ’Fahrzeugdialog geöffnet’ Abhängigkeit 16.3. Hinweis Verschachtelte Abhängigkeiten 190 In der Vorbereitung müssen wir prüfen, ob der Dialog bereits geöffnet wurde. Es könnte nämlich sein, dass ein voriger Testfall den Dialog bereits geöffnet und nicht mehr geschlossen hat. Das Attribut ’Wartezeit’ des Warten auf Komponente Knotens steht hier auf ’0’, weil wir erwarten, dass der Dialog offen sein soll, wenn nicht, dann muss dieser ohnehin geöffnet werden. Wir sollten auch eine Abhängigkeit ’Zubehördialog geöffnet’ erstellen, welche ähnlich zur ’Fahrzeugdialog geöffnet’ Abhängigkeit, den Zubehördialog öffnet. Nach Erstellen der Abhängigkeiten müssen wir nun die entsprechenden Testschritte aufzeichnen und die Testfälle erstellen. Die Testschritte wurden schon erstellt und können als Prozeduren in der entsprechenden Dialog Packages Struktur gefunden werden. Die Testfälle sollten in einem Testfallsatz namens ’Verschachtelte Abhängigkeiten’ zusammengefasst erstellt werden. Dieser Testfallsatz sollte zwei weitere Testfallsatz beinhalten. Das erste ist ’Tests für den Fahrzeugdialog’, das zweite ’Tests für den Zubehördialog’. Der Testfallsatz ’Tests für den Fahrzeugdialog’ beinhaltet die Implementierungen der Testfälle 1 und 2, sowie eine Bezug auf Abhängigkeit auf die ’Fahrzeugdialog geöffnet’ Abhängigkeit. Der zweite Testfallsatz ’Tests für den Zubehördialog’ beinhaltet die Implementierung des Testfalles 3 und eine Bezug auf Abhängigkeit auf die Abhängigkeit ’Zubehördialog geöffnet’. Abbildung 16.9: Implementierung der Testfälle Wenn Sie nun den obersten Testfallsatz starten, werden Sie sehen, dass QF-Test das SUT zuerst stoppt, das kommt von der Abhängigkeit des vorherigen Beispieles. Danach wird das SUT gestartet und es werden die Schritte von Testfall 1 und Testfall 2 ausgeführt und schlussendlich die Schritte von Testfall 3. Wenn Sie im Protokoll einen genaueren Blick auf den Anfang von Testfall 3 werfen, dann werden Sie sehen, dass auch die Aufräumen der ’Fahrzeugdialog geöffnet’ Abhängigkeit ausgeführt wurde. Dies passierte, weil die Abhängigkeit ’Fahrzeugdialog geöffnet’ nicht mehr benötigt wurde. Testfall 3 hat allerdings die ’Zubehördialog geöffnet’ Abhängigkeit benötigt und hat deshalb deren Vorbereitung durchlaufen. Da diese beiden Abhängigkeiten auf der ’SUT gestartet’ Abhängigkeit aufbauen, wurde deren Aufräumen Sequenz nicht ausgeführt. 16.4. Fehler- und Exceptionbehandlung 191 Abbildung 16.10: Protokoll von verschachtelten Abhängigkeiten Das Verschachteln von Abhängigkeiten und die Möglichkeit, eine Aufräumen Sequenz nur bei Bedarf aufzurufen, ermöglichen Ihnen relativ viele vor- und nachbereitende Schritte in eine Abhängigkeit zu packen. Ein anderer Anwendungsfall für den JCarConfigurator könnte eine Abhängigkeit ’Fahrzeug angelegt’ sein, welche sicherstellt, dass das verwendete Fahrzeug vorher angelegt wird. 16.4 Fehler- und Exceptionbehandlung 16.4.1 Fehlerbehandlung In der Testsuite qftest-4.0.6/doc/tutorial/advanced-demos/de/dependencies_work.qft finden Sie einen Testfallsatz ’Tests mit Fehlerbehandlung’. Der zweite Testfall ist fehlerhaft. 16.4. Fehler- und Exceptionbehandlung 192 Abbildung 16.11: Testsuite für Fehlerbehandlung Angenommen wir wollen bestimmte Aktionen auslösen, die nach einem fehlerhaften Testfall ausgeführt werden sollen. In unserem Fall könnten wir im Fehlerfall einfach das SUT stoppen. Dies könnte notwendig sein, um zu garantieren, dass die folgenden Testfälle auf einer sauberen Umgebung aufsetzen können. Wir wissen bis jetzt, dass die Vorbereitung Sequenz vor jedem Testfall ausgeführt wird und die Aufräumen nur bei Bedarf ausgeführt wird. Aber wie können wir jetzt diese spezielle Fehlerbehandlung implementieren? Die Lösung ist der so genannte Fehlerbehandlung Knoten für eine Abhängigkeit. Wenn Sie auf die geschlossene Aufräumen Sequenz klicken, können Sie mit Rechtsklick Knoten einfügen→Abhängigkeiten→Fehlerbehandlung . Im Fehlerbehandlung Knoten können Sie die Schritte für das Stoppen des SUT aufrufen. Die Abhängigkeit SUT gestartet sollte nun wie folgt aussehen: Abbildung 16.12: Abhängigkeit mit Fehlerbehandlung Führen Sie nun den gesamten Testfallsatz ’Tests mit Fehler’ aus und öffnen Sie das Protokoll nachdem die Ausführung abgeschlossen ist. Im Protokoll können Sie sehen, dass der Fehlerbehandlung Knoten nach dem zweiten Testfall ausgeführt wurde. 16.4. Fehler- und Exceptionbehandlung 193 Abbildung 16.13: Protokoll einer Abhängigkeit mit Fehlerbehandlung 16.4.2 Exception Behandlung Im vorigen Abschnitt haben wir gelernt, dass man mit Fehlerbehandlung Knoten Schritte definieren kann, welche bei fehlerhaften Testfälle ausgeführt werden. Neben Fehlern können allerdings auch Exceptions beim Testlauf auftreten. Eine Exception ist ein unerwartetes Verhalten während der Testausführung, z.B. ein Dialog erscheint und blockiert die Ausführung oder eine Komponente konnte nicht gefunden werden. Wie soll man mit solchen Exceptions umgehen? In der Demotestsuite qftest-4.0.6/doc/tutorial/advanced-demos/de/dependencies_work.qft finden Sie ein Beispiel Testfallsatz namens ’Tests mit Exception’. Natürlich können Sie entsprechende Testschritte mit einem Try-Catch umrunden und eine dedizierte Exceptionbehandlung in jedem Testfall implementieren. Im Beispiel Testfallsatz wurde dies so implementiert. Dieser Ansatz kann jedoch zu viel Redundanz führen und die Testfälle werden noch unleserlicher. 16.4. Fehler- und Exceptionbehandlung 194 Abbildung 16.14: Try-Catch Knoten in Testfälle Unser Ziel ist es nun, die Redundanz in den Testfällen zu reduzieren und die einheitliche Exceptionbehandlung an eine zentrale Stelle zu verschieben. Diese zentrale Stelle wird unsere Abhängigkeit sein. Der erste Schritt hierfür ist das Einfügen des Catch Knotens in eine Abhängigkeit. Hierzu müssen Sie auf dem geschlossenen Fehlerbehandlung Knoten einen Rechtsklick ausführen und Knoten einfügen→Ablaufsteuerung→Catch einfügen. Danach können wir die Schritte aus einem der Catch Knoten in den neuen Knoten verschieben und in den Testfälle die Prozeduraufrufe aus dem Try Block herausziehen und den Try Block dann löschen. Die Testsuite sieht nun so aus: 16.4. Fehler- und Exceptionbehandlung 195 Abbildung 16.15: Testsuite mit Catch Nun können Sie den Testfallsatz ’Tests mit Exception’ starten. Der zweite Testfall wirft eine IndexNotFoundException, weil das ausgewählte Modell nicht existiert. Diese Exception sollte nun vom globalen Catch Knoten der Abhängigkeit behandelt werden. Hinweis Wenn Sie den Debugger aktiviert haben, wird QF-Test den Testlauf an der Stelle unterbrechen, wo die Exception auftritt. In unserem Fall können Sie dann die Exception mit dem Knopf ’Exception erneut werfen’ weiterwerfen oder den Debugger mittels dem Menüeintrag Debugger→Debugger aktivieren deaktivieren. Öffnen Sie nach der Ausführung das Protokoll um nachzusehen, was passiert ist. 16.5. Mehr zu Abhängigkeiten 196 Abbildung 16.16: Protokoll der Ausführung Abhängigkeit mit Catch In einem normalen Projekt sollten Sie mindestens einen solchen global Catch Knoten für ’TestException’ erstellen. Dieser Knoten sollte dann auch entweder die Prozedur qfs.swing.cleanup.closeAllModalDialogs oder die Prozedur qfs.swt.cleanup.closeAllModalDialogsAndModalShells aufrufen. Diese Prozeduren schließen jeglichen modalen Dialog, d.h. jedes Fenster, das die Ausführung der Tests blockieren könnte. 16.4.3 Zusammenfassung Sie haben nun gesehen, dass man ein robustes Recovery Management für Testfälle mittels Fehlerbehandlung und noch mehr mittels Catch Knoten für eine Abhängigkeit implementieren kann. In den meisten Projekten ist ein globaler Catch Knoten sehr wichtig, besonders im Falle von ComponentNotFoundExceptions und ModalDialogExceptions. 16.5 Mehr zu Abhängigkeiten Im oberen Bereich haben wir gesehen, dass man verschiedene Abhängigkeiten verschachteln kann und dass die Aufräumen Sequenz einer Abhängigkeit nur dann ausgeführt wird, wenn die entsprechende Abhängigkeit nicht mehr benötigt wird. Wir können eine Abhängigkeit auch so konfigurieren, dass die Aufräumen jedes mal ausgeführt wird. Das kann mittels Setzens der Option ’Aufräumen erzwingen’ der Abhängigkeit bewerkstelligt werden. Es gibt noch viel mehr Interessantes über Abhängigkeiten zu entdecken, z.B. kann man die Ausführung der Aufräumen auch mittels Variablen steuern. Diese Variable heißt charakteristische Variable. Diese und mehr Details finden Sie im Handbuch im Kapitel Abhängigkeiten. Dieser Ansatz könnte verwendet werden, um eine Abhängigkeit ’Login’ zu 16.5. Mehr zu Abhängigkeiten 197 erstellen, deren Aufräumen, d.h. das Ausloggen, nur dann ausgeführt wird, wenn sich der Inhalt der Variable Benutzer ändert. Eine detaillierte Beschreibung von Abhängigkeiten finden Sie im Handbuch im Kapitel Abhängigkeiten. Kapitel 17 Automatische Erstellung von Basisprozeduren [60 Min] Dieses Kapitel beschreibt, wie man mit QF-Test Prozeduren für die GUI Elemente automatisch erzeugen kann. Der Vorteil dieser Technik ist, dass man nicht mehr jeden Schritt des Tests einzeln aufzeichnen muss. Darüberhinaus wird auch eine standardisierte Package und Prozeduren Struktur bereitgestellt. Sie finden die fertiggestellten Beispiele in der Datei qftest-4.0.6/doc/tutorial/ advanced-demos/de/automated_procedures.qft . Es gibt auch noch eine zweite Testsuite qftest-4.0.6/doc/tutorial/ advanced-demos/de/automated_procedures_work.qft für Ihre eigenen Implementierungen. 17.1 Einführung Wenn wir für alle Features des JCarConfigurator Tests erstellen wollen, so müssen wir auch Aktionen für jedes involvierte GUI Element aufzeichnen. Der JCarConfigurator ist eine kleine Applikation mit vielleicht fünf Dialogen und ca. dreißig GUI Elementen. Das Erstellen der wichtigsten Testfälle für diese Applikation wird ein bis zwei Tage dauern. Aber stellen Sie sich ein großes Projekt vor, wie ein ERP System mit über fünfzig Dialogen und hunderten von GUI Elementen. Hier wird das Erstellen der Testfälle erheblich länger dauern und ebenso könnte die Wartung der Tests schwieriger werden. Als ersten organisatorische Schritt empfehlen wir, jeden Testschritt als Prozedur zu erstellen und diese dann von den entsprechenden Testfälle aufzurufen. Wenn Sie Ihre Tests in unterschiedlichen Testsuiten organisieren, dann könnten Sie diese in zwei Schichten aufteilen. Die erste Schicht enthält nur GUI Komponenten bezogene Prozeduren und die zweite Schicht beinhaltet nur Testfälle, welche die Prozeduren der ersten 17.1. Einführung 199 Schicht aufrufen. Der Ansatz jeden Testschritt als Prozedur zu implementieren bringt uns in die Lage, unsere Arbeit in zwei Bereich aufzuteilen: 1. Erstellung und Wartung von Prozeduren, welche die Testschritte repräsentieren 2. Erstellung und Wartung von Testfällen QF-Test liefert nun ein Feature, das diese Basisprozeduren für GUI Elemente automatisch erstellt. Wenn Sie dieses Feature benutzen, reduziert sich der Erstellungsaufwand für Testsuiten und Testfälle drastisch und es unterstützt Sie in der Erstellung wartbarer Testsuiten. Sie finden in der Demotestsuite qftest-4.0.6/doc/tutorial/ advanced-demos/de/automated_procedures.qft einige Testfälle, die mit diesem Feature erstellt worden sind. 17.2. Automatische Erstellung von Prozeduren 200 Abbildung 17.1: Bildschirmabbild der Testsuite Die folgenden Abschnitte beschreiben nun, wie man diese Prozeduren erstellt und die Testfälle organisiert. 17.2 Automatische Erstellung von Prozeduren Bitte öffnen Sie die Demotestsuite qftest-4.0.6/doc/tutorial/ advanced-demos/de/automated_procedures_work.qft Diese Datei enthält einen Testfallsatz, der sich auf die Abhängigkeit ’Start SUT’ bezieht. 17.2. Automatische Erstellung von Prozeduren 201 Abbildung 17.2: Die Testsuite automated_procedures_work.qft Zuerst müssen wir das SUT starten. Hierfür selektieren Sie die Abhängigkeit und drücken auf ’Wiedergabe starten’. Sobald das SUT läuft, können wir die Testschritte aufzeichnen. Normalerweise würden wir jetzt auf ’Aufnahme starten’ klicken, die entsprechenden Schritte aufzeichnen und dann die Aufnahme mit ’Aufnahme beenden’ stoppen. Danach würden wir die Aufnahme reorganisieren, d.h. Prozeduren erstellen und diese parametrisieren. Genau diese Schritte können jetzt automatisiert erfolgen. Wir werden jetzt zuerst die Basisprozeduren für das Hauptfenster erstellen. Bevor wir loslegen, müssen wir allerdings die Konfiguration von QF-Test anpassen. Öffnen Sie die Optionen mittels Bearbeiten→Optionen . Dann wechseln Sie nach ’Aufnahme’ -> ’Prozeduren’. Dort ändern Sie den Wert von ’Konfigurationsdatei für Prozedurenaufnahme’ auf den Pfad unserer Demokonfigurationsdatei nämlich qftest-4.0.6/demo/procbuilder/carconfig-procbuilderdef.qft. Danach klicken Sie auf ’OK’. Details über diese Datei erfahren Sie im nächsten Abschnitt. Nachdem Sie die Konfiguration geändert haben, fahren Sie mit folgenden Schritten fort: • Drücken Sie den ’Prozeduren erstellen’ Knopf • Klicken Sie mit der rechten Maustaste auf das SUT • Wählen Sie ’Ganzes Fenster’ aus • Drücken Sie den ’Prozeduren erstellen’ Knopf nochmals. Jetzt erstellt QF-Test die Basisprozeduren für das Hauptfenster. Sie sollten nun unter Prozeduren ein Package namens procbuilder sehen. Dieses Package enthält weitere Packages und Prozeduren, die Aktionen für die einzelnen GUI Elemente und den gesamten Dialog beinhalten. Hinweis Die aktuelle Konfiguration erstellt das Package JCarConfigurator als Container für alle Prozeduren innerhalb des Hauptfensters. 17.2. Automatische Erstellung von Prozeduren 202 Abbildung 17.3: Die aufgezeichneten Prozeduren Beachten Sie, dass die involvierten Komponenten auch unter Fenster und Komponenten aufgezeichnet worden sind. Der nächste Schritt ist das Prüfen, ob die erstellten Prozeduren für uns nützlich oder einige überflüssig sind. Werfen wir nun einen genaueren Blick auf die erstellten Packages: Package JCarConfigurator Inhalt Dieses Package beinhaltet alle Prozeduren für Aktionen auf Komponenten des JCarConfigurator Fensters. Dieses Package wurde aufgrund der aktuellen Konfiguration erstellt, welches die Hierarchie der Komponenten beachtet. Tabelle 17.1 Das Package JCarConfigurator enthält folgende Packages: 17.2. Automatische Erstellung von Prozeduren Package MenuBar VehicleTablePanel check check-window get select set set-window wait 203 Inhalt Dieses Package enthält alle Prozeduren für Aktionen auf Menüeinträge des SUT. In unserem Fall finden wir hier nur Prozeduren für das Klicken auf die einzelnen Menüeinträge. Dieses Package enthält alle Prozeduren für Aktionen auf Komponenten auf den ’VehicleTablePanel’ Panel des SUT. In unserem Fall finden wir hier nur Prozeduren für das Objekt ’VehicleTable’, weil es die einzige Komponente auf diesem Panel ist. Dieses Package enthält Prozeduren um Komponenten zu prüfen. Dieses Package enthält Prozeduren um die alle Komponenten eines Fenster zu prüfen. Dies ist eine Containerprozedur. Dieses Package beinhaltet Prozeduren um Werte von Elementen auszulesen und zurückzuliefern, z.B. das Auslesen eines Textes. Dieses Package beinhaltet Prozeduren um Elemente auszuwählen. In unserem Fall gibt es eine Prozedur um einen Tab des TabbedPanes auszuwählen. Dieses Package beinhaltet Prozeduren um Komponenten zu setzen. In unserem Fall sind das Setzmethoden für die Textfelder. Dieses Package beinhaltet Prozeduren um alle Komponenten des Fensters mittels einen Prozeduraufrufes zu setzen. In unserem Fall ruft die erstellte Prozedur alle ’set’ Prozeduren des JCarConfigurator Fensters auf. Diese Containerprozedur ist auch eine typische Workflowprozedur. Dieses Package beinhaltet alle Prozeduren, um auf diverse Komponenten zu warten. Tabelle 17.2 In unserem Fall sind alle Prozeduren nützlich. Wir können also das gesamte JCarConfigurator Package aus dem procbuilder Package direkt unter Prozeduren verschieben. Bitte vergessen Sie nicht beim ’Referenzen aktualisieren’ Dialog auf ’Ja’ zu klicken. Jetzt können die Prozeduren von Testfällen genutzt werden. Schlussendlich sieht unsere Testsuite so aus: 17.2. Automatische Erstellung von Prozeduren 204 Abbildung 17.4: Die Testsuite mit den Prozeduren Wiederholen Sie nun diese Aufnahme für das ’Sondermodelle’ und das ’Zubehör’ Panel. Sie müssen dann nur noch die neuen Prozeduren und Packages in das ’JCarConfigurator’ Package verschieben. In unserem Fall sind das nur die Packages ’SpecialsPanel’ und ’AccessoryTablePanel’. Die vollständige Testsuite sieht nun so aus: Abbildung 17.5: Die Prozeduren für alle Panels Nun können wir wirklich die Testfälle mit den automatisch generierten Prozeduren erstellen. Sie können natürlich vorher noch Prozeduren für alle Dialoge, z.B. den ’Fahrzeug’ Dialog erzeugen. Diesen Dialog erreichen Sie im SUT mittels ’Optionen’ -> ’Fahrzeuge’. Ebenso gilt dies für den ’Sondermodelle’ und ’Zubehör’ Dialog. Sie müssen nicht immer das gesamte Fenster aufzeichnen. Sie können auch durch Auswahl von ’Nur Komponente’ Prozeduren für eine bestimmte Komponente generieren oder mittels ’Komponente mit Kindern’ Prozeduren für ein gesamtes Panel erzeugen. 17.3. Konfiguration der automatischen Erstellung 17.3 Konfiguration der automatischen Erstellung 17.3.1 Einführung 205 Im vorigen Beispiel haben wir die Datei qftest-4.0.6/demo/procbuilder/carconfig-procbuilderdef.qft als Konfigurationsdatei für die automatische Generierung benutzt. In diesem Abschnitt wollen wir uns die Konfigurationsmöglichkeiten von QF-Test genauer ansehen. Öffnen Sie hierzu diese Datei. Abbildung 17.6: Die aktuelle Konfiguration Das Package procbuilder ist das Wurzelpackage für alle erstellten Packages. Wenn Sie einen anderen Namen für dieses Package verwenden wollen, können Sie dieses einfach umbenennen. Wenn Sie dieses Package öffnen, dann sehen Sie die ’Klassen’ Ebene. Diese Ebene beschreibt die Klassen der GUI Komponente, welche für die Erstellung berücksichtigt werden sollen. Die nächste Ebene beinhaltet dann die Informationen über die zu erstellende Packagestruktur und deren Prozeduren. Sie können eine detaillierte Beschreibung im Handbuch im Kapitel Die Procedure Builder Definitionsdatei finden. 17.3. Konfiguration der automatischen Erstellung 17.3.2 206 Erstes Beispiel In unserem ersten Beispiel wollen wir eine neue Konfigurationsdatei erstellen, welche wir selbst Schritt für Schritt aufbauen. Bitte führen Sie folgende Schritte durch: • Öffnen Sie eine neue Testsuite und speichern diese. Geben Sie der Testsuite einen Namen, wie ’mySettings.qft’. • Erstellen Sie ein neues Package mit dem Namen ’myProcedures’. Bis jetzt sieht die neue Testsuite folgendermaßen aus: Abbildung 17.7: Die eigene Konfigurationsdatei Jetzt sind wir bereit die Prozedurenvorlagen für spezielle Klassen zu erstellen. Wir sollten zuerst Prozeduren für Textfelder des Hauptfensters erstellen. In unserem Projekt könnte es interessant sein, den Inhalt der Textfelder zu prüfen, daher brauchen wir Prozeduren hierfür. Um diese Prozeduren zu erstellen, müssen wir ein Package unter ’myProcedures’ anlegen. Dieses Package sollte den Namen ’javax_swing_JTextField’ haben. ’javax.swing.JTextField’ ist die Klasse aller Textfelder, allerdings ist ein ’.’ nicht in Packagenamen erlaubt, deshalb ersetzen wir diesen mit ’_’. Dieses Package wird QF-Test nun instruieren, Prozeduren für eine Komponente zu erstellen, sobald diese von der entsprechenden Klasse ist. Das ist sehr wichtig, damit wir unsere Prozedurvorlagen auf Klassenebene definieren können. Nun erstellen wir eine Vorlage für die eigentliche Prüfprozedur der Komponenten. Die Prozedurvorlage sollte allerdings noch Teil eines weiteren Packages sein. Der Name des Packages sollte die Gruppe der Prozeduren bezeichnen, z.B. ’checkers’. Nach Erstellung des ’checkers’ Package, sollten Sie eine Prozedur ’checkText’ zu diesem Package hinzufügen. Die Prozedur sollte einen ’Check Text’ Knoten beinhalten, welcher zum Prüfen von Texten geeignet ist. Bitte fügen Sie diesen ’Check Text’ Knoten mittels Rechtsklick und Auswahl von ’Knoten einfügen’ -> ’Check Knoten’ -> ’Check Text’ ein. Setzen Sie das Attribut ’client’ auf $(client), das Attribut QF-Test component ID auf ’dummy’ und das Attribut ’text’ auf $(text). 17.3. Konfiguration der automatischen Erstellung 207 Nach dem Bestätigen dieser Eingaben werden wir selbstverständlich eine Warnung erhalten, in der wir darauf hingewiesen werden, dass eine Komponente namens ’dummy’ nicht existiert. Diese Warnung dürfen wir an dieser Stelle ignorieren. Die Testsuite sieht nun wie folgt aus: Abbildung 17.8: Die checkText Prozedur Die Prozedur sollte einen Parameter ’text’ mit einem leeren Standardwert beinhalten. 17.3. Konfiguration der automatischen Erstellung 208 Abbildung 17.9: Die checkText Prozedur mit Parametern Die erste Prozedurvorlage ist nun fast vollständig, jetzt müssen wir uns allerdings noch über einen Aspekt Gedanken machen. Jede Komponente hat ihre eigene und eindeutige QF-Test ID, also wäre es praktisch, wenn diese QF-Test ID bereits bei der Erstellung berücksichtigt wird, anstatt diese manuell nachzupflegen. Außerdem wollen wir, dass die Prozeduren komponentenbezogene Namen aufweisen statt einfach nur ’checkText’. Der Platzhalter <COMPID> steht in QF-Test für die QF-Test ID der aktuellen Komponente. Also müssen wir den Prozedurnamen in checkText_<COMPID> ändern. Wir sollten auch den Platzhalter <COMPID> direkt in das QF-Test component ID Attribut des ’Check Text’ Knotens einfügen. Schlußendlich sieht unsere Prozedurvorlage wie folgt aus: 17.3. Konfiguration der automatischen Erstellung 209 Abbildung 17.10: Der <COMPID> Platzhalter Jetzt können wir unsere eigene Konfigurationsdatei verwenden. Hierfür müssen wir QFTest noch mitteilen, dass diese Datei verwendet werden soll. Öffnen Sie die Optionen mittels Bearbeiten→Optionen und wechseln Sie in den ’Aufnahme’ -> ’Prozeduren’ Bereich. Dort setzen Sie den Pfad Ihrer eigenen Datei im Attribut ’Konfigurationsdatei für Prozedurenaufnahme’. Danach bestätigen Sie die Änderung mit ’OK’. Danach starten Sie den JCarConfigurator. Wenn dieser vollständig gestartet wurde, fahren Sie mit folgenden Schritten fort: • Drücken Sie den ’Prozeduren erstellen’ Knopf • Führen Sie Rechtsklick auf dem SUT aus • Selektieren Sie ’Ganzes Fenster’ • Drücken Sie den ’Prozeduren erstellen’ Knopf. Gratulation! Sie haben eigene Testschritte mit QF-Test erstellt. 17.3. Konfiguration der automatischen Erstellung 210 Abbildung 17.11: Die selbst erstellten Testschritte 17.3.3 Den aktuellen Text verwenden Die ’checkText’ Prozeduren haben den Parameter ’text’ für den zu prüfenden Text. Bis jetzt müssen wir den zu prüfenden Text immer beim Aufruf der Procedure angeben. Stellen wir uns nun ein Szenario vor, in dem wir die Standardwerte der Textfelder nach dem Start prüfen wollen. In diesem Fall müssten wir jedem einzelnen Prozeduraufruf der vier ’checkText’ Prozeduraufrufe den entsprechenden Parameterwert mitgeben. QF-Test bietet einen Platzhalter, um den aktuellen Text während der Prozedurerstellung einzubinden. Hierfür müssen wir in der Konfigurationsdatei den Standardwert des Parameters ’text’ auf <CURRENTVALUE> setzen. Danach sollten Sie sich versichern, dass das Package myProcedures nicht mehr unter Prozeduren existiert, damit wir die Prozeduren neu aufzeichnen können. Falls dieses Package doch existieren sollte, wird ein neues Package myProcedures1 erstellt um die Eindeutigkeit der erstellten Packages zu gewährleisten. Erstellen Sie nun die Prozeduren wie im vorigen Beispiel. Die geänderte Konfigurationsdatei: 17.3. Konfiguration der automatischen Erstellung Abbildung 17.12: Die Konfigurationsdatei mit dem aktuellen Text Die neu erstellten Prozeduren: Abbildung 17.13: Die generierten Prozeduren mit dem aktuellen Text 211 17.3. Konfiguration der automatischen Erstellung 17.3.4 212 Generieren von Container Prozeduren Im vorigen Beispiel haben wir ’checkText’ Prozeduren für die einzelnen Textfelder erstellt. Sie sollten nun selbstständig in der Lage sein ’set’ Prozeduren, zum Setzen des Textes zu erstellen. Bis jetzt haben wir allerdings nur mit einzelnen Komponenten gearbeitet. In einigen Testszenarien kann es durchaus von Interesse sein, dass man mit einem Prozeduraufruf alle Textfelder eines Dialoges oder eines speziellen Panels prüft. Ein weiteres Szenario wäre das Setzen aller sichtbaren Textfelder. Solche Prozeduren arbeiten mit Container-Komponenten, deshalb heißen diese Prozeduren Container Prozeduren In unserem Fall wollen wir nun eine Prozedur erstellen, die alle vier ’checkText’ Prozeduren des JCarConfigurator aufruft. Aber wie erstellen wir diese? Zuerst müssten wir ein weiteres Klassenpackage in ’mySettings.qft’ einfügen. Der Name des Packages sollte ’javax_swing_JFrame’ sein. Das Hauptfenster des JCarConfigurator ist eine Instanz von javax.swing.JFrame, deshalb sollten wir dieses Klassenpackage erstellen. Darin sollte wir ein Typpackage namens ’checkers-window’ erstellen. Das Typpackage sollte wiederum eine Prozedur checkTextOfElements_<COMPID> beinhalten, welche die einzelnen Checks aufruft. Wir benutzen hier den Platzhalter <COMPID>, damit wir erkennen können zu welchem Dialog die erzeugte Prozedur gehört. Der nächste Schritt ist das Spezifizieren des Prozedureninhaltes. Schauen wir mal, wie man das macht. Wir haben vier Textfelder, welche alle mittels der Prozedur checkText_<COMPID> geprüft werden können. QF-Test ermöglicht es uns nun, alle vier Prozeduraufrufe mit nur einem zu konfigurieren. Daher fügen Sie bitte einen Prozeduraufruf Knoten in diese Prozedur ein. Sie müssen dann die Prozedur javax_swing_JTextField.checkers.checkText_<CCOMPID> aufrufen. Die Konfigurationsdatei nach dieser Änderung: Abbildung 17.14: Die Vorlage für die Containerprozedur 17.3. Konfiguration der automatischen Erstellung 213 Als letzten Schritt muss man QF-Test so konfigurieren, dass auch wirklich eine Containerprozedur und keine normale Komponentenprozedur erstellt wird. Hierfür muss man den Wert @FORCHILDREN im ’Bemerkung’ Attribut der Prozedur checkTextOfElements_<COMPID> eintragen. Abbildung 17.15: Die Verwendung von @FORCHILDREN Jetzt können Sie die Prozeduren, wie im vorigen Beispiel aufzeichnen. Vergessen Sie bitte nicht das ’myProcedures’ Package vorher aus Prozeduren zu löschen. Jetzt sollten unter Prozeduren folgende Prozeduren erstellt werden: 17.3. Konfiguration der automatischen Erstellung 214 Abbildung 17.16: Die generierten Containerprozeduren Hinweis QF-Test ersetzt den ’Klassen’ Teil des Prozeduraufrufes durch den Namen des Konfigurationspackages. In unserem Fall ist dies ’myProcedures’. 17.3.5 Der aktuelle Wert der Kindkomponente (210) Wir können uns eine ähnliche Situation wie in Den aktuellen Text verwenden beschrieben, auch für die Containerprozeduren vorstellen. Im obigen Beispiel haben wir <CURRENTVALUE> hierfür benutzt. Jetzt müssen wir den Parameter ’text’ bei den einzelnen Prozeduraufrufen in der Containerprozedur ’checkTextElements’ setzen. Dafür fügen wir diesen Parameter zum Prozeduraufruf in unserer Konfigurationsdatei ’mySettings.qft’ hinzu. Der Wert sollte auf <CCURRENTVALUE> gesetzt werden. 17.3. Konfiguration der automatischen Erstellung 215 Abbildung 17.17: Konfiguration mit <CCURRENTVALUE> Wenn wir jetzt die Prozeduren nochmals erstellen, werden Sie sehen, dass die aktuellen Werte zu den Prozeduraufrufen hinzugefügt worden sind. Vergessen Sie bitte wieder nicht, vorher das ’myProcedures’ Package aus Prozeduren zu löschen. Abbildung 17.18: Testsuite mit <CCURRENTVALUE> Wenn Sie sich die generierte Prozedur ’checkTextElements’ genauer anschauen, so 17.3. Konfiguration der automatischen Erstellung 216 werden Sie bei jedem Prozeduraufruf den gesetzten Text sehen. Vielleicht wäre es von Vorteil wenn dieser ’text’ Parameter auch als Standardwert der Containerprozedur zur Verfügung stünde. Um dies zu erreichen, müssten Sie einen weiteren Parameter zur Prozedurvorlage hinzufügen. Der Name des Parameters ist <CCOMPID> und der Wert <CCURRENTVALUE>. Danach müssen Sie den Wert des ’text’ Parameters beim Prozeduraufruf in $(<CCOMPID>) ändern. Die Konfiguration sollte also wie folgt aussehen: Abbildung 17.19: Parameter für Containerprozeduren Wenn Sie nun wiederum die Prozeduren erstellen, dann werden Sie sehen, dass die ’checkTextElements’ Prozedur vier Parameter bekommen hat und die aktuellen Werte der Textfelder jeweils als Standardwerte eingetragen worden sind. Darüber hinaus hat jeder einzelne Prozeduraufruf für den Parameter ’text’ eine Variable als Wert, die wie die QF-Test ID der Komponente heißt, welche auch gleichzeitig der Name des Parameters ist. 17.3. Konfiguration der automatischen Erstellung 217 Abbildung 17.20: Parameter für die Containerprozedur in der Testsuite 17.3.6 Weitere Konfigurationsmöglichkeiten Wie Sie in den vorigen Abschnitten gesehen haben gibt es eine Menge Konfigurationsmöglichkeiten für die automatische Prozedurenerstellung. Es gibt jedoch noch weitere Möglichkeiten. Um mehr darüber zu erfahren schauen Sie bitte ins Handbuch ins Kapitel Die Procedure Builder Definitionsdatei.
© Copyright 2024 ExpyDoc