Das Akronym AJAX für "Asynchronous JavaScript and XML" wird allgemein mit
modernen Webanwendungen assoziiert, die sich interaktiver anfühlen als die klassischen
<FORM>-basierten Anwendungen und vom Look&Feel her schon
fast an Desktop-Applikationen herankommen. Hinter diesem gemeinsamen Akronym steckt
allerdings ein ganzer Zoo von Webframeworks, auf denen solche Anwendungen basieren. Jedes
davon setzt eigene Schwerpunkte und kommt mit einem eigenen Satz von Widgets. Solche
Webframeworks stellen für QF-Test und jedes andere automatisierte Testwerkzeug aus folgenden
Gründen ein Problem dar:
-
Die Komponentenhierarchie wird automatisch aus abstrakten Widgets wie Button oder List
generiert. Ein Widget wird dabei oft mittels diverser <DIV>
Knoten implementiert. Dies führt zu einer sehr tief verschachtelten Hierarchie mit
geringer Struktur.
-
IDs werden entweder gar nicht zugewiesen oder automatisch generiert, was für
Regressionstests noch problematischer ist.
-
Die asynchrone Kommunikation mit dem Webserver und die dynamische Erstellung von DOM
Knoten kann Probleme beim Timing verursachen.
Es gibt kein Allheilmittel, mit dem sich diese Probleme generisch lösen lassen. In
vielen Fällen kann QF-Test trotzdem ohne weiteres Zutun mit AJAX Anwendungen interagieren.
Dabei sind Wiedererkennung und Performanz allerdings nicht ideal. Optimale Testbarkeit
kann nur mit Hilfe von Spezialfunktionen erreicht werden, die genau auf ein Webframework
zugeschnitten sind und sich dessen Eigenheiten zu Nutze machen.
Das Video 'Die Explosion der
Komplexität in der Web Testautomatisierung eindämmen' zeigt eindrucksvoll die Reduktion tief
geschachtelter DOM-Strukturen durch QF-Test.
Für die folgende Liste von Webframeworks bietet QF-Test Resolver für eine optimierte Behandlung:
Der angegebene Kurzname kann in Aufrufen der Prozedur
installCustomWebResolver
im Parameter resolver
angegeben werden, siehe Abschnitt 46.1.3.
QF-Test ist sogar in der Lage, automatisch festzustellen, ob Ihre Webanwendung eines dieser
Frameworks benutzt und einen passenden Resolver, wie unten beschrieben, einzuhängen.
Ein Webframework-Resolver besteht aus verschiedenen Resolvern und anderen Funktionen, die
speziell für ein bestimmtes Framework entwickelt werden. Vor allem versucht QF-Test,
den DOM Knoten Klassen zuzuweisen, die den zugehörigen abstrakten Widgets entsprechen
und Knoten auf Zwischenebenen, die nur ein Detail der Framework-Implementierung sind,
aus der Hierarchie herauszufiltern. Die Attribute 'Name', 'Merkmal' und
'Weiteres Merkmal' werden passend zum Framework ermittelt und Events werden so auf den
korrekten DOM Knoten wiedergegeben, dass dies möglichst exakt einer Aktion von einem
echten Anwender entspricht. Diese Maßnahmen reduzieren die Hierarchie der Komponenten
drastisch und erhöhen Performanz und Zuverlässigkeit der Wiedererkennung und
Wiedergabe gleichermaßen. Zudem werden Timing und Synchronisation besonders
unterstützt.
Zwangsläufig unterscheiden sich Komponenten und Events für eine Webanwendung mit und
ohne aktiviertem Framework Resolver signifikant und sind nicht zueinander kompatibel. Daher
sollte die Entscheidung, ob ein Framework Resolver verwendet wird, so früh wie möglich
getroffen werden. Andernfalls müssen entweder bestehende Tests neu implementiert
werden, nachdem der Resolver aktiviert wird, oder Tests mit und ohne Resolver müssen
sauber voneinander getrennt werden. Wenn ein Resolver für Ihre Anwendung verfügbar
ist, sollten Sie ihn praktisch immer auch einsetzen, außer Ihre Tests sind bereits zu
umfangreich, weitgehend vollständig und stabil.
Die Implementierung eines Webframework Resolvers ist ein fortlaufender Prozess. Da Änderungen
an einem Resolver Auswirkungen darauf haben können, wie Komponenten aufgenommen und
erkannt werden, muss sichergestellt sein, dass Sie Ihre QF-Test Version aktualisieren
können, ohne die Kompatibilität bestehender Tests zu gefährden. Hierzu werden Framework
Resolver mit einer eigenen dreistelligen Version versehen, beginnend mit Version
1.0.0, mit folgender Bedeutung:
-
Bei einer Änderung der Minor Version, z.B. 1.0.1, ist die Kompatibilität nicht
berührt.
-
Eine Änderung der Medium Version, z.B. 1.1.0, bedeutet, dass mit niedrigerer Medium
Version aufgenommene Tests immer noch wiedergegeben werden können, bei Aufnahme
neuer Sequenzen aber Komponenten anders aufgenommen werden können. Dies ist nicht
kritisch, es kann aber besser sein, solche Neuaufnahmen zu vermeiden, wenn die
Vorteile der neuen Version nicht überwiegen.
-
Bei einer Änderung der Major Version, z.B. 2.0.0, kann auch die Kompatibilität der
Wiedergabe verloren gehen, was dann eine Neuaufnahme oder manuelle Anpassung der
betreffenden Komponenten erforderlich macht.
Webframework Resolver werden über die 'Prozedur' qfs.web.ajax.installCustomWebResolver
in der Standardbibliothek
qfs.qft
aktiviert, bei der Sie die zu verwendende Version angeben müssen.
Sie können wahlweise nur die Major Version angeben, in welchem Fall QF-Test die höchste
verfügbare Medium.Minor Version für diese Major Version verwendet. Dies ist
üblicherweise die beste Option und wird in der mit Hilfe des Schnellstart-Assistenten
erstellten Startsequenz verwendet (vgl. Kapitel 3). Alternativ
können Sie die Major.Medium Version festlegen, oder sogar die exakte
Major.Medium.Minor Version und so Ihre Tests mit der Version des Resolvers ausführen,
mit der sie erstellt wurden.
Jedes Webframework hat seine eigene Methoden, um eindeutige IDs zu
vergeben.
In diesem Abschnitt finden Sie die entsprechenden Methoden für die
unterstützten Frameworks von QF-Test:
Die einfachste Variante ist es, das 'ID' Attribut <div id="myId"/>
für alle notwendigen Komponenten zu setzen.
IDs können mittels folgendem Code gesetzt werden:
var container = Ext.create('Ext.container.Container', {
id: 'MyContainerId',
...
});
.
Als Alternative können Sie auch
container.getEl().set({ 'qfs-id': 'myId' });
aufrufen. In diesem Fall müssen Sie allerdings einen
NameResolver implementieren, der 'qfs-id' als Namen für QF-Test setzt.
Die einfachste Variante ist die Methode
widget.getElement().setId("myId");
für die erzeugten Elemente aufzurufen.
Alternativ können Sie auch
widget.ensureDebugId("myId")
aufrufen. Allerdings
müssen Sie in diesem Fall die Datei xxx.gwt.xml
anpassen, damit diese IDs auch wirklich gesetzt werden. Hierfür
müssen Sie <inherits
name="com.google.gwt.user.Debug"/>
eintragen.
Es ist auch möglich ein eigenes Attribut 'qfs-id' für die Identifikation zu setzen.
Hierfür rufen Sie die Methode setAttribute("qfs-id", "myId")
auf.
Dieses Attribut kann nun mittels NameResolver für QF-Test verwendet werden.
Die einfachste Variante ist es, das 'ID' Attribut <p:inputText
id="myId"/>
für alle notwendigen Komponenten in der xhtml Definition zu
setzen.
Die einfachste Variante ist es, das 'ID' Attribut <p:inputText
id="myId"/>
für alle notwendigen Komponenten zu setzen, bei
einem existierenden Element wie folgt:
$(element).attr("id","myId");
Die einfachste Variante ist es, das 'ID' Attribut <p:inputText
id="myId"/>
für alle notwendigen Komponenten zu setzen.
Sie müssen das 'ID' Attribut im Sourcecode oder über
den grafischen Editor setzen.
Die einfachste Variante ist es, das 'ID' Attribut <p:inputText
id="myId"/>
für alle notwendigen Komponenten in der xhtml Definition zu
setzen.
Es gibt keinen Standardweg. Sie können entweder ein eigenes Attribut in der Generierung
des DOMs an die Knoten oder eine Eigenschaft an die setData
Methode des Qooxdoo
Widgets hängen. Diese Eigenschaft können Sie dann per Resolver auswerten.
Ab RAP Version 2.2 wird ein Name, der mit widget.setData("name", "myId")
vergeben wird, genau wie bei SWT direkt von QF-Test ausgewertet. Das Feld kann nur benutzt werden wenn es zuvor über WidgetUtil.registerDataKeys("name");
registriert wurde.
Für RAP Versionen älter als 3.0.0 funktioniert auch die folgende Technik, die aber
nicht empfohlen wird, da sie vom SWT Standard abweicht und zuätzlich erfordert, den
Webserver mit einer besonderen Option zu starten.:
Rufen Sie die Methode widget.setData(WidgetUtil.CUSTOM_WIDGET_ID,
"myId");
für jedes notwendige Element auf.
Nun müssen Sie noch Ihre Webserver Umgebung mit folgendem zusätzlichen
Parameter starten -Dorg.eclipse.rap.rwt.enableUITests=true
.
Bitte beachten: Der VM Parameter wurde ab RAP 2.0 umbenannt, für RAP Versionen vor
2.0 lautet er -Dorg.eclipse.rwt.enableUITests=true
.
Sie müssen das 'ID' Attribut im Sourcecode oder über
den grafischen Editor setzen.
Die einfachste Variante ist es, die Methode widget.setID("id")
für alle notwendigen Komponenten aufzurufen.
Die einfachste Variante ist es, die Methode widget.setId("id")
(widget.setDebugId("id")
für Vaadin Version < 7)
für alle notwendigen Komponenten aufzurufen.
Sie können auch eine eigene Stylesheet Klasse mittels
widget.setStyleName("qfs-id=myId")
hinzufügen. Diese muss dann in einem NameResolver für QF-Test
ausgewertet werden.
QF-Test verwendet die Widget-ID, welche auch in den
zul
Dateien verwendet wird. Daher sollten die
meisten IDs nutzbar sein.
Das ZK Framework bietet auch einen eigenen IDGenerator an, um
IDs zu vergeben. Dies kann allerdings ziemlich aufwendig sein,
hier ist es besser sich auf die Standardalgorithmen von QF-Test zu verlassen.