Expecco GUI Tests Extension Reference

Aus expecco Wiki (Version 2.x)
Wechseln zu: Navigation, Suche


Die "expecco GUI Tests Extension" (GUI Browser) unterstützt die Erstellung von Testsequenzen für grafische Benutzeroberflächen (GUIs) in expecco. Das Werkzeug ist nahtlos in die expecco Benutzeroberfläche integriert. Es dient als gemeinsame Basis für verschiedenste GUI-Technologien (Qt, Java/Swing, Android, MFC, etc). Die "expecco GUI Tests Extension" bietet neben der Möglichkeiten zum Aufzeichnen von Testsequenzen auch Unterstützung zum interaktiven Entwicklung von Testsequenzen, sowie Informationen über die Struktur der Benutzeroberfläche und Zustände sowie Eigenschaften der Bedienelemente. Einzelne Aktionen oder ganze Sequenzen können zunächst ausprobiert und anschließend in die Testsequenz übernommen werden ("exploratives Testen").

Hauptmerkmale

  • Nahtlose Integration in die expecco-Benutzeroberfläche
  • Ein gemeinsames Werkzeug für verschiedene UI-Technologien
  • Visualisierung des Aufbaus der Benutzeroberfläche (Komponentenstruktur)
  • Informationen über verschiedene Zustände und Eigenschaften der einzelnen Bedienelemente
  • Unterstützung beim Auffinden von Bedienelemente durch Hervorhebung, Vorschaubilder und "Mouse-Over" Feedback
  • Filterung von passenden Aktionsblöcken aus der Block-Bibliothek abhängig von der jeweiligen UI-Technologie
  • Erstellung von Testsequenzen mittels "Drag and Drop" und/oder automatischer Aufzeichnung
  • Experimentelles Ausprobieren von Blöcken, Testsequenzen und Bedienelement-Pfaden
  • Übernehmen von Testsequenzen in das Testprojekt

Beschreibung

Schaltfläche zum öffnen der Benutzeroberfläche

Die "expecco GUI Tests Extension" bildet eine einheitliche Basis zur Interaktion mit Anwendungen mit grafischer Benutzeroberfläche (GUI). Dabei werden unterschiedliche Technologien unterstützt. Die eigentliche Anbindung an die GUI-Anwendung und deren Steuerung wird von der jeweiligen Erweiterung (plugin) für die konkrete UI-Technologie realisiert. Entsprechende Erweiterungen sind für eine Vielzahl von Technologien erhältlich - z.B. Qt, Java/Swing, MFC, DevExpress, Android, iOS und Windows Mobile. Es muss also mindestens ein konkretes UI-Technologie Plugin vorhanden sein um den GUI Browser sinnvoll verwenden zu können.

Andererseits können auch mehrere Anwendungen, auch auf unterschiedlichen Technologien basierende, gleichzeitig in einem gemeinsamen Testszenario angesprochen und getestet werden. Somit können, z.B. bei Integrationstests, End-to-End Tests durchgeführt werden, welche innerhalb eines Testlaufs sowohl mobile als auch webbasierte und klassische Oberflächen bedienen und verifizieren.

Nachdem in expecco ein Projekt erstellt oder geöffnet wurde, kann über die Schaltfläche "GUI Browser Öffnen" die Benutzeroberfläche der "expecco GUI Tests Extension" geöffnet werden.

Benutzeroberfläche

Abb1: Gliederung der Hauptansicht
Abb2: Bedienfluss

Eine Übersicht über den Aufbau, die Verwendung und die Funktionen der Benutzeroberfläche. Abbildung 1 Zeigt die Gliederung der Hauptansicht. In Abbildung 2 wird der Bedienfluss dargestellt.

Verbindungsaufbau
Eine Auflistung der verfügbaren Benutzer-Oberflächen Technologien. Per Klick auf eine der Schaltflächen wird der Verbindungsaufbau der jeweiligen UI-Technologie gestartet. Nach dem Verbindungsaufbau erscheint die Anwendung in der Benutzeroberflächenstruktur (Hierarchie der Komponenten).
Benutzeroberflächenstruktur
Zeigt alle verbundenen und nicht verbunden Anwendungen. Unter jeder Anwendung wird der Aufbau der Benutzeroberfläche mit allen verfügbaren Bedienelementen dargestellt. Beim Aufklappen einer nicht verbundenen Anwendung wird versucht die Verbindung wieder herzustellen, falls diese verloren ging oder noch nicht bestand. Die Selektion eines Bedienelements oder einer Anwendungen aktualisiert die Menge der dazu passenden Aktionen sowie die Ansicht der Block-Bibliothek, Eigenschaftenübersicht, Bedienelementübersicht und den Bedienelementpfad.
Werkzeuge
Eine Auflistung verschiedener Werkzeuge. Ein Klick auf eine der Schaltflächen löst die Aktionen aus. Einige Aktionen sind von der Selektion in der Benutzeroberflächenstruktur abhängig.
Alle Verbindungen Trennen
Trennt alle Verbindungen aller Technologien.
Ausgewählte Verbindung trennen
Trennt die Verbindung bezüglich des in der Benutzeroberflächenstruktur ausgewählten Bedienelementes.
Aktualisieren
Aktualisiert die obersten Bedienelemente aller verbundenen Anwendungen.
Kinderelemente erneut Laden
Aktualisiert die Kinderelemente bezüglich des in der Benutzeroberflächenstruktur ausgewählten Bedienelementes.
Hervorheben
Hebt das in der Benutzeroberflächenstruktur ausgewählte Bedienelement in der Benutzeroberfläche hervor.
Zeiger Folgen
Wenn diese Funktion aktiviert wurde, folgt die Selektion der Benutzeroberflächenstruktur automatisch dem unter dem Mauszeiger befindlichen Bedienelement (Quick-Scan).
Aufzeichnung für alle Anwendungen beginnen
Beginnt die automatische Aufzeichnung einer Testsequenz für alle verbundenen Anwendungen. Während der Interaktion mit der/den Benutzeroberfläche(n) wird die Testsequenz im Sequenzeditor generiert. Befindet sich bereits eine Sequenz im Sequenz-Editor, so wird diese fortgesetzt.
Aufzeichnung für alle Anwendungen beenden
Beendet die Aufzeichnung für alle verbundenen Anwendungen.
Eigenschaftenübersicht
Listet verfügbare Eigenschaften des ausgewählten Elements auf. Selektion einer der Eigenschaften ändert die Ansicht der Block-Bibliothek, so dass nur Blöcke die sich auf diese Eigenschaft beziehen, angezeigt werden.
Block-Bibliothek
Zeigt die verfügbaren Blöcke aus der Technologiebibliothek, für das in der Benutzeroberflächenstruktur ausgewählte Element an. Unter "Aktionen" werden die Blöcke aufgeführt, die passend zum Element sind, beispielsweise das Setzen des Textes einer Label-Komponente. Unter "Eigenschaften" werden die Blöcke aufgeführt, die für eine unter "Eigenschaftenübersicht" ausgewählte Eigenschaft relevant sind, wie zum Beispiel das Abfragen der Sichtbarkeit.
Wird ein Block selektiert, so ändert sich die Ansicht der Editoransicht auf "Test" und der Block wird angezeigt.
Zieht man den Block mit der Maus über die Editoransicht, so wechselt die Ansicht auf "Sequenz". Lässt man den Block in der Sequenz fallen, so wird er als Schritt an die Sequenz angefügt.
Editoransicht
Unter "Test" wird der in der Blockbibliothek ausgewählte Block dargestellt. Die Pins können editiert werden. Anschließend kann der Block gegen die Anwendung ausgeführt werden. Die Editoransicht wechselt dabei auf "Lauf". Die Ausführung des Blocks kann hier überprüft werden. Aus der Test-Ansicht heraus kann der Block direkt mittels der Schaltfläche "In Sequenz Übernehmen" in die Testsequenz übernommen werden. Der Block wird als Schritt an die Testsequenz angefügt.
Die "Sequenz"-Ansicht stellt die aktuelle Testsequenz dar. Diese kann manuell oder durch Aufzeichnung erweitert werden. Die Testsequenz lässt sich ausführen, die Ansicht wechselt dann auf "Lauf". Hier kann die Ausführung der gesamten Testsequenz überprüft werden. In der "Sequenz"-Ansicht lässt sich die gesamte Sequenz in das aktuelle Projekt übertragen. Dazu wird die Schaltfläche "In Projekt Übernehmen" ausgewählt.
Bedienelement-Pfad
Zeigt den Pfad des in der Benutzeroberflächenstruktur ausgewählten Bedienelements. Der Pfad kann verändert werden; insbesondere sollten längere verschachtelte Containerpfade durch "*" ersetzt werden, damit die Adressierung der Komponente möglichst unabhängig von späteren Änderungen der UI-Hierarchie werden. Mit der Schaltfläche "Pfad-Prüfen" wird sichergestellt, dass der geänderte Pfad immer noch das in der Benutzeroberflächenstruktur ausgewählte Bedienelement referenziert.
Bedienelementübersicht
Zeigt Informationen des in der Benutzeroberflächenstruktur ausgewählten Bedienelementes an und stellt, falls möglich, eine Vorschau dar. Ein Klick auf die Vorschau öffnet das Bild in Originalgröße.


Bedienelementpfad (XPath)

Der "Bedienelementpfad" dient als Referenz auf Bedienelemente innerhalb der Benutzeroberfläche. Er ist vergleichbar mit der XPath-Notation im XML Umfeld. Komponentenpfade werden bei der Testentwicklung festgelegt und später, bei der Testausführung, verwendet um UI-Komponenten zu referenzieren. Der Pfad eines ausgewählten Bedienelements wird unten im "Bedienelement-Pfad" Feld angezeigt, und bei Auswahl eines Elements automatisch aktualisiert. Umgekehrt kann er an dieser Stelle auch geändert und überprüft werden, welche(s) Element(e) durch einen gegebenen Pfad referenziert werden. Der Pfad muss nicht vollständig sein - er kann dynamische Teile enthalten. Dies erhöht die Flexibilität und macht die Testsequenz robuster gegenüber einer möglichen späteren Änderung der getesteten Benutzeroberfläche. Insbesondere gegenüber Änderungen der Hierarchie, z.B. wenn weitere Containerelemente eingefügt werden.

Hinweis: Viele Benutzeroberflächen ändern während der Ausführung die Struktur dynamisch. Oft werden Container- und Bedienelemente während dem Lauf hinzugefügt oder entfernt. In solchen Fällen sind dynamische Teile im Pfad sehr hilfreich.

Pfade Definieren

Ein typischer Pfad kann wie folgt aussehen:

/frame[@name='Notepad']/root pane/layered pane/panel/panel/panel/tool bar/push button[2]

Dieser Pfad beschreibt die vollständige Adressierung des zweiten Buttons in einer Toolbar, welche ihrerseits in einer verschachtelten Containerhierarchie (panels) liegt.

Der Pfad wird beschrieben durch eine Liste von Identifikatoren, getrennt durch und beginnend mit "/". Jeder einzelne Identifikator beschreibt eine Unterkomponente des bereits durch den linken Teilpfad beschriebenen Elements. "/frame[@name='Notepad']" referenziert das Hauptfenster der Anwendung. "root pane", "layered pane", "panel" etc. referenzieren jeweils das korrespondierende Kindelement. Zur Referenzierung einer einzelnen konkreten Komponente wird der Pfad beginnend mit dem obersten Bedienelement schrittweise verfolgt.

Im Beispiel wird zuerst versucht, das Fenster mit Namen "Notepad" zu finden. Das Fenster hat ein oder mehrere Kinder, dessen Identifikator zu "root pane" passt. "root pane" wiederum hat Kinder die zum Identifikator "layered pane" passen und so weiter.

Die Syntax eines jedes individuellen Identifikators ist:

/<KnotenIdentifikator><[Optionaler Selektor]>

KnotenIdentifikator

Der KnotenIdentifikator beschreibt den Typ des Bedienelementes das gesucht wird.

Mögliche Identifikator:

Der Typ des Bedienelements
Das Ergebnis sind eine oder mehrere Bedienelemente die dem angegebenen Typ entsprechen.
Der "Jeder" Identifikator ("*")
Löst den Rest des Pfades unter Verwendung alle Kindelemente, unabhängig vom Typ des aktuell aufzulösenden Identifikators auf.

Beispiel:
Vollständiger Pfad:

/frame[@name='Notepad']/root pane/layered pane/panel/panel/panel/tool bar/push button[2]

Der selbe Pfad mit "*" Identifikatoren:

/*[@name='Notepad']/*/layered pane/*/panel/*/tool bar/push button[2]

Diese zwei Pfade adressieren in obigem Fall das selbe Bedienelement. Jedoch ist die zweite Variante unempfindlicher gegenüber geänderten Komponenten in der Hierarchie. Zum Beispiel könnten die Entwickler der zu testenden Anwendung eine panel-Komponente durch eine box-Komponente ersetzen. Der erste Pfad würde dann im Testlauf zu einem Fehler wegen nicht auflösbarem Pfad führen. Zu beachten ist, dass der "*"-Identifikator zur als Platzhalter einer einzelnen Komponente dient. Um den Pfad auch robust gegenüber zusätzlich in die Hierarchie eingebrachte Komponenten zu machen, sollte die "//"-Notation (siehe unten) verwendet werden.

Selektor

Der Selektor ist optional. Er wird benötigt um Bedienelemente mit gleichem Typ zu unterscheiden. Gibt es beispielsweise 3 Buttons als Kinder eines Bedienelements, so kann mit dem Selektor der zu referenzierende Button festgelegt werden. Der Selektor wird in eckigen "[ ]" Klammern angegeben. Der Selektor wird nach der Auflösung des KnotenIdentifikators auf das Ergebnis angewendet. Gibt es zum Beispiel ein Bedienelement mit zwei Buttons und zwei Checkboxen als Kinder, und der Identifikator liefert als Ergebnis 2 Buttons, so wird der Selektor auf diese 2 Buttons angewendet.

Mögliche Selektoren:

Der "Index" Selektor
Wählt das Bedienelement anhand des Index. Der Index ist 1 basiert (i.e. [1] bezieht sich auf die erste Komponente).
Der "Schlüssel-Wert" Selektor (engl. "Key-Selector")
Wählt das Bedienelement dessen Schlüssel den angegebenen Wert hat. Die Menge der möglichen Schlüssel ist abhängig von der jeweiligen UI-Technologie, der betroffenen Komponente und deren Attribute. Typische Schlüssel sind "name", "id", "label", "value" etc. Bei einigen Komponenten sind auch dynamische Schlüssel möglich, so dass diese erst während der Laufzeit angelegt werden.

Beispiel (Index Selector):

/*/tool bar/push button[2]

Wählt den zweiten Button innerhalb der Toolbar aus.

Beispiel (Schlüssel Selector):

/*/tool bar/push button[@name='Save As...']

Wählt den Button aus dessen Attribut "name" (= Schlüssel) den Wert "Save As..." hat.


Achtung: Vorsicht ist geboten, wenn Attributwerte abhängig von der Landessprache oder anderen Inhalten der App sind. Falls Sie Attribute finden, welche Sprachunabhängig und konstant sind, sollten Sie diese verwenden (z. B. "id", "refID", "uuid" etc.). Wenn nicht, halten Sie die Datenwerte getrennt von den Aktionsblöcken (z.B. in Attachments, externen Dateien oder expecco-Variablen) und konstruieren den xPath mithilfe dieser dynamisch in expecco zur Testlaufzeit. Damit wird es leichter, später weitere Sprachvarianten oder geänderte Button-Labels zu unterstützen.

Platzhalter Schreibweise

Die Platzhalterschreibweise ("//") kann Pfade stark verkürzen und flexibel gegenüber zusätzlich eingefügten Hierarchieebenen machen. "//" ersetzt dabei ganze Teile des Pfades. Der Vergleich findet nicht nur auf Kinder eines Bedienelementes statt, sondern auf ganze Teilpfade.

Beispiel:
Angenommen der vollständige Pfad eines Buttons wäre folgender:

/frame[@name='Notepad']/root pane/layered pane/panel/panel/panel/tool bar/push button[@name='Save As...']

Außerdem angenommen, die Anwendung hat nur einen Button mit dem Namen "Save As...", welche sichtbar ist. Dann kann der Pfad mittels Platzhalterschreibweise wie folgt verkürzt werden:

//push button[@name='Save As...']

Noch kürzer ginge es, wenn nur ein Bedienelement mit Namen "Save As..." existiert. Dann wäre folgender Pfad möglich:

//*[@name='Save As...']

Auch ist es möglich, wie im folgenden Beispiel, nur Teile des Pfades mit Platzhaltern zu versehen:

/*[@name='Notepad']//panel//tool bar/*[@name='Save As...']

Hinweis: Die verkürzten Pfade in den oben gezeigten Beispielen sind wesentlich unanfälliger gegenüber Änderungen im Layout der Benutzeroberfläche. Jedoch erhöht es je nach Anwendung und Benutzeroberfläche auch die Wahrscheinlichkeit, dass mehrere passende Bedienelemente gefunden werden. Dies wird dann ebenfalls zur Laufzeit zu einem Fehler führen ("Nicht eindeutiger Komponentenpfad"). In obigem Beispiel könnte dies passieren, wenn im UI neben dem Button auch ein Menueintrag mit dem selben Text existiert. In der Praxis wird die Auswahl des geeigneten Pfades immer einen Kompromiss aus Flexibilität (möglichst kurz) und Eindeutigkeit darstellen.



Copyright © 2014-2016 eXept Software AG