Wie wird es gemacht?
Der Trojaner hängt sich in die Ereignisbehandlung der Applikation ein. Bei Qt geschieht das über
qApp->installEventFilter(EventFilter)
qApp ist die globale Instanz von QApplication, EventFilter ist das Filterobjekt, dessen Methode eventFilter(QObject, Qevent) überschrieben wird.
Der Trojaner kennt mindestens drei Betriebsmodi: Aufzeichnen, Abspielen und Informationen liefern. Im Aufzeichnungsmodus wird in der Regel das Widget farblich hervorgehoben, über dem sich der Mauszeiger gerade befindet. Abhängig von der derzeitigen Benutzerinteraktion führt der Trojaner Folgendes aus:
- Maus bewegen: Widget unter der Maus identifizieren und farblich hervorheben durch Abfangen des sogenannten Paint Events.
- Maus klicken/loslassen: Ermitteln eines eindeutigen Namens des geklickten Widgets sowie der Klickposition innerhalb des Widgets, die an das GUI-Test-Tool geschickt werden.
- Text eingeben: Tastaturcode an Testwerkzeug schicken.
Die GUI-Elemente werden in der Regel rot hervorgehoben, was etwa 10 Prozent der Menschen vor das Problem stellt, zugeben zu müssen, dass sie farbenblind sind. Wer das ist, könnte an der Stelle eingreifen und die Hervorhebungsfarbe ändern.
Im Abspielmodus wird dieser Vorgang umgekehrt. Über den Widget-Namen ermittelt der Trojaner das Widget-Objekt. Auf die aktuelle Position des Widgets rechnet er die aufgezeichnete Klickposition innerhalb des Widgets dazu, bewegt mit Betriebssystemmitteln die Maus auf diese Position und führt die aufgezeichnete Anzahl von Klicks durch. Dadurch dass der Trojaner die Position des Widgets erst zur Laufzeit vom Widget-Objekt erfragt, lässt sich ein Widget an beliebige Positionen des Bildschirms verschieben und wird trotzdem erkannt. Wenn ein anderes Widget über dem zu klickenden Widget liegt, landet der Klick zwar an der korrekten Bildschirmposition, jedoch nicht beim gewünschten Widget. Das stellt sicher, dass die Fernsteuerung nur die Widgets ansprechen kann, die auch der menschliche Bediener sieht. Andernfalls würde der Test Layoutfehler nicht finden können.
Der Informationsmodus liefert Informationen über die Widgets der zu testenden Applikation. Entweder fordert das GUI-Testwerkzeug die Struktur und die Parameter aller lebenden Widgets in einem Rutsch an, oder es ermöglicht dem Benutzer, auf ein GUI-Element zu zeigen, und fragt dann die Parameter des Widgets ab.
Wer ist da?
Eine der wesentlichen, wenn nicht die wichtigste Funktion eines GUI-Testwerkzeugs ist, die GUI-Elemente sicher und eindeutig erkennen zu können. Würde jedem Widget einer GUI-Applikation durch den Entwickler ein unveränderlicher, global eindeutiger Namen gegeben, wäre das Kodieren und die Pflege von Testskripts einfach. In der Praxis werden GUI-Applikationen allerdings nicht in erster Linie in Hinblick auf einfache Testbarkeit entwickelt, sodass die Identifikation von Widgets durch andere Mittel erfolgen muss. Oft will man auch die historisch gewachsenen Anteile des Quellcodes der Applikation nicht verändern. Vielfach wird die GUI zur Laufzeit dynamisch erzeugt, sodass sich individuelle Widget-Namen gar nicht vergeben lassen, ohne große Änderungen an der Applikation vorzunehmen.
Einfacher Beispieldialog (Abb. 2)
Deshalb verwenden GUI-Test-Tools ausgefeilte Mechanismen, um Widgets zu erkennen. Zunächst werten sie den Namen des Widgets aus (nicht zu verwechseln mit dem dargestellten Text, der je nach eingestellter Sprache beim nächsten Testlauf ein ganz anderer sein kann). Bei Qt geschieht das über die Property objectName. Ist sie nicht gesetzt , wird als Nächstes der Klassenname, zum Beispiel QLineEdit, ausgewertet.
An der Stelle ergibt sich eine erste Möglichkeit für den Testentwickler, in den Code des Werkzeugs einzugreifen. Wenn es aufgrund der Besonderheiten der eigenen Applikation möglich ist, eine bestimmte Eigenschaft oder eine Kombination von Eigenschaften der Widgets zur sicheren Identifikation zu verwenden, lässt sich der Trojaner entsprechend ergänzen.
Zusätzlich wird die Stellung des Widgets in der Architektur der GUI über seine Parent-, Grand-Parent-, Grand-Grand-Parent-Eigenschaft herangezogen. Da diese Informationen in der Regel immer noch keine eindeutige Identifikation ermöglichen, erhält das Widget eine laufende Nummer, die sich aus seiner Konstruktionsreihenfolge oder seiner Stellung in der Focus Chain (Erstellungsreihenfolge) ableitet.
Für das im Beispieldialog selektierte QLineEdit-Widget erhält man unter Verwendung des Klassennamens folgendes Ergebnis:
QDialog#0|QFrame#0|QTabWidget#0|QWidget#0|QGroupBox#0|QLineEdit#0
Würde man das zweite QLineEdit klicken wollen, erhielte man folgenden Namen:
QDialog#0|QFrame#0|QTabWidget#0|QWidget#0|QGroupBox#0|QLineEdit#1
Das gute Verhalten mit Qt erstellter GUI-Applikationen im Vergleich zu Java-Anwendungen erreicht der Entwickler durch Optimierungen, die einem bei der GUI-Testerstellung gelegentlich wieder "auf die Füße fallen".
Einige GUI-Elemente von Qt, die so aussehen, als wären sie eigenständige Objekte, sieht Qt als ein einziges, großes Widget an. Das sind Menüs, Karteireiter und Listen. Für diese Elemente einen eindeutigen, unveränderlichen Bezeichner zu finden erweist sich als besonders schwierig. Die Tools behelfen sich oft damit, dem Widget-Namen weitere Indizes hinzuzufügen. Das klappt so lange gut, bis man neue Elemente einfügt. Wenn der Entwickler seinem Tester helfen will, sollte er darauf achten, neue Elemente nur noch am Ende anzuhängen, zum Beispiel neue Karteireiter.
Um besondere grafische Effekte wie Transparenz oder Fenster ohne Rahmen zu erzeugen, werden häufig eigene GUI-Elemente entwickelt und mehrere GUI-Elemente übereinander gelegt. Trifft das für die Applikation zu, muss der Testentwickler wahrscheinlich Hand anlegen und dem Trojaner helfen, das GUI-Element zu erkennen.
Wenn der Test plötzlich Widgets nicht mehr findet, ohne dass an der zu testenden GUI etwas geändert wurde, liegt es vermutlich daran, dass Widgets der GUI-Applikation zufälligerweise in einer anderen Reihenfolge angelegt wurden. Bei größeren Applikationen muss die Reihenfolge der Widget-Erzeugung nicht unbedingt deterministisch sein. In dem Fall ist den betroffenen Widgets ein fester Objektname zu geben.
Ab sofort kann man sich mit Vorträgen für die neue Konferenz zu Agile ALM, Continuous Delivery und DevOps bewerben.




Am 5. und 6. Juni trifft sich in Toulouse die Eclipse-Community zur Erstauflage der EclipseCon France. Bis 26. Mai kann man sich noch zum Frühbucherpreis registrieren.