Auf die eine oder andere Weise war jeder mit Situationen konfrontiert, in denen etwas Ungewöhnliches in einer banalen Umgebung passierte. Ein ähnlicher Fall ist uns beim Testen einer neuen Anwendung in einer hundertmal getesteten Umgebung passiert. Eine Überraschung für uns war die Verwendung einiger HTML5-Funktionen im Front-End bzw. die Unfähigkeit, das Testen von Drag & Drop-Vorgängen mit Standard-Selenium WebDriver-Tools zu automatisieren. Wir möchten über diese Erfahrung sprechen.

Stellen Sie sich ein Projekt vor, das dem vorherigen technologisch sehr ähnlich ist (unserer Meinung nach hatte es einen kleinen negativen Einfluss auf das korrekte Verständnis und die Analyse des aufgetretenen Problems), aber die Version von Angular zwischen Projekten wurde von 1.x auf 5.x geändert und die Selenide-Bibliothek für UI-Autotests wurde hinzugefügt .
Die entwickelte Webanwendung hatte eine Seite mit einer bestimmten Gruppe von Entitäten, die untereinander verschoben werden konnten. Stellen Sie sich unsere Überraschung vor, als ein Versuch, einen Selbsttest zum Überprüfen von Drag & Drop-Funktionen mit Selenide-Werkzeugen durchzuführen, erfolglos war. Es scheint, dass was schief gegangen sein könnte? Beim vorherigen Projekt hat in einer ähnlichen Testumgebung alles perfekt funktioniert.
Zuerst haben wir die Drag & Drop-Funktion der Selenid- und Selenium-Funktionen im aktuellen Browser anhand eines Beispiels einer anderen Webanwendung überprüft. Alles arbeitet. Aktualisierte Versionen, man weiß nie ...
Wir beschlossen zu prüfen, ob wir ziehen und dort. Und die falsche Auswahl von Elementen bei der Verwendung von Angular ist ziemlich einfach. Wir haben uns mit einem Front-End-Entwickler zusammengesetzt und festgestellt, dass Drag & Drop-Elemente richtig ausgewählt wurden.
Im Allgemeinen funktioniert die Testumgebung, die Testmethoden sind korrekt geschrieben, Drag & Drop "von Hand" funktioniert, aber der Autotest funktioniert nicht. Und dafür gibt es auf den ersten Blick keine Gründe.
Schließlich haben wir uns mit der Tatsache des Problems abgefunden und im Internet nach einer Lösung gesucht. Was war unsere Überraschung, als wir die offene Ausgabe
Chrome WebDriver # 3604 vom 03.04.2016 fanden . Denken Sie nur daran, dass es seit dem Frühjahr 2016 offiziell ein Problem mit fehlerhaftem Drag & Drop in Chrome WebDriver gibt, ganz zu schweigen von anderen Browsern. Nein, es funktioniert sicherlich, aber nicht bei Verwendung von HTML5. Und wie sich bei der Analyse des Problems herausstellte, verwendete unsere Anwendung die Drag & Drop-Implementierung mit HTML5.
Was sind die Drag & Drop-Implementierungen zum Testen in HTML5? Im Internet wurden zwei Lösungen gefunden:
- Verwenden Sie die Java-Bibliothek awt.Robot (oder einen Clicker eines Drittanbieters).
- Verwenden Sie Javascript.
Wir haben wahrscheinlich ein wenig Geld verdient oder sind in dem Problem begraben, aber ich werde sofort reservieren, dass die erste gewählte Lösung nicht zu uns passt :)Was kann über die Implementierung auf Robot gesagt werden:
- Wir fangen die Maus ab und emulieren vollständige Benutzeraktionen.
- Wir verwenden Selen, um die Koordinaten der Elemente zu bestimmen.
- Da Selenium-Elemente verwendet werden, müssen Sie die Locators nicht ändern. Wir versuchen im Projekt, xpath zu verwenden.
- Es ist in Java geschrieben, die Syntax ist intuitiv, gute Dokumentation.
Aber etwas an der JavaScript-Implementierung kam mir in den Sinn:
- Alles geschieht in JavaScript im Browser (Aktionen sind vor den Augen des Testers verborgen und diese Aktionen stören den Code).
- Von den js-Bibliotheken zum Testen von Drag & Drop im Internet wurde eine gefunden, deren Quelle nicht so leicht zu finden war.
- Die gefundene Bibliothek muss mit einer Datei fertiggestellt werden, die Ihren Anforderungen entspricht, da nur sauberes Drag & Drop implementiert wird. Und wir brauchten zum Beispiel Ziehen -> Verschieben -> Halten -> Ablegen;
- Die Bibliothek ist als jQuery-Add-On implementiert. Daher muss die jQuery-Struktur verstanden werden.
- Wir müssen Locators in CSS umwandeln (jquery funktioniert nicht mit xpath).
- Es ist unmöglich, nach Selenelementen zu suchen. Sie müssen die Locators mit „Stiften“ verkleben.
Auf den ersten Blick war die erste Lösung viel praktischer und wurde getestet.
Im Allgemeinen funktioniert die Lösung ... Im Verlauf ihrer Entwicklung wurden jedoch ihre Problembereiche klar.
- Mausbewegungen oder die Minimierung des Browsers während der Ausführung der Tests führen zu Störungen im Verlauf der Tests und deren Sturz.
- Mit JUnit / TestNG können keine Tests parallel ausgeführt werden. Es sei denn, Sie müssen durch separate Aufgaben in CI parallelisieren.
- Maus kann auf Remote-Maschine nicht über Selenium Grid / Selenoid gesteuert werden;
- Im Falle eines Browserabsturzes kann Robot einfach auf etwas auf dem Desktop oder in einer anderen geöffneten Anwendung klicken / ziehen.
Am Ende jedoch die JavaScript-Implementierung ...Ich möchte sofort sagen, dass wir es geschafft haben, das Problem der Verwendung von xpath-Locators mit dem jQuery-Plugin jquery.xpath.js zu lösen.
Die Bibliothek drag_and_drop_helper.js (Quelle
hier ) wurde zum Hauptwerkzeug für die Steuerung von Drag & Drop-Vorgängen. Es macht keinen Sinn, ihre Arbeit zu sortieren, aber wie wir etwas später daran gearbeitet haben.
Nun direkt zur Implementierung in den Tests. Bei Selenide ist alles einfach. Bevor Sie Drag & Drop verwenden können, müssen Sie die verwendeten JS-Bibliotheken laden:
StringBuilder sb = new StringBuilder(); sb.append(readFile("jquery-3.3.1.min.js")); sb.append(readFile("jquery.xpath.min.js")); sb.append(readFile("drag_and_drop_helper.js")); executeJavaScript(sb.toString());
Natürlich muss jQuery geladen werden, wenn es nicht bereits in der Anwendung enthalten ist.
In der Originalversion der Bibliothek reicht es aus, Folgendes zu schreiben:
executeJavaScript("$('" + source + "') .simulateDragDrop({ dropTarget: '" + target + "'});");
Quelle und Ziel sind CSS-Locators für Drag & Drop-Elemente.
Wie oben erwähnt, verwenden wir im Projekt häufig xpath-locators. Nach einer kleinen Verfeinerung begann die Bibliothek, diese zu akzeptieren:
executeJavaScript("$(document).xpath('" + source + "').simulateDragDrop({ dropTarget: '" + target + "'});");
Nun eigentlich zur Bibliothek drag_and_drop_helper.js. Der simulateEvent-Codeblock enthält Teile, die für bestimmte Mausereignisse verantwortlich sind. Es macht keinen Sinn, die möglichen Ereignisse von Drag & Drop-Vorgängen in HTML5 aufzulisten. Diese Informationen sind leicht zu finden.
Zum Testen mussten wir eine Funktion implementieren, die das Element bewegt und die Maus auf dem Zielelement hält. Und dies wird, wie in der Quellbibliothek, nicht bereitgestellt.
Analog haben wir das Dragenter-Ereignis zur Bibliothek hinzugefügt (zwischen Dragstart und Drop).
type = 'dragenter'; var dragenterEvent = this.createEvent(type, {}); dragenterEvent.dataTransfer = event.dataTransfer; this.dispatchEvent($(options.dropTarget)[0], type, dragenterEvent);
Dies reicht jedoch nicht aus. Immerhin wird das Hold-Event sofort abgeschlossen. Das Festlegen einer festen Pause zwischen DragEnter- und Drop-Ereignissen schien nicht die bequemste Option zu sein. Schließlich ist zunächst nicht bekannt, wie lange die Anwendung benötigt, um ein Ereignis zu verarbeiten. Anzahl und Zeitpunkt der Überprüfungen in Tests sind nicht bekannt. Die Verzögerung zwischen diesen Ereignissen sollte zumindest überschaubar sein. Stattdessen haben wir beschlossen, die Drag & Drop-Tests in Stufen zu unterteilen und nicht den gesamten Satz von Mausereignissen zu emulieren, dh die Möglichkeit hinzuzufügen, die Liste der beteiligten Ereignisse über den Parameter zu verwalten.
Und alles scheint in Ordnung zu sein, neue Mängel sind nicht aufgetreten, und einige der alten sind nicht mehr so, und vor allem werden die zugewiesenen Aufgaben ausgeführt. Es scheint, dass alles perfekt ist. Moderne Entwicklungswerkzeuge legen jedoch die Verarbeitung von weit entfernt von zwei Ereignissen fest und verwenden verschiedene Parameter des verschobenen Elements. Angenommen, wir haben diese Lösung beim Ausführen von Drag & Drop, die DragStartListener-Fehler verursacht. Aber da es nichts kaputt macht, haben wir nichts anderes geändert. In einer anderen Anwendung müssen Sie diesen Moment jedoch wahrscheinlich beenden.
Wir wollen das Obige zusammenfassen. Überraschenderweise eine Tatsache! HTML5 wurde bereits 2013 veröffentlicht, Browser unterstützen es bereits seit mehreren Jahren, Anwendungen wurden dafür entwickelt, aber webDriver weiß leider immer noch nicht, wie es seine Funktionen nutzen soll. Das Testen von Drag & Drop-Vorgängen muss mit Tools von Drittanbietern implementiert werden, die Architektur komplizieren und alle möglichen Tricks ausführen. Ja, es gibt solche Werkzeuge und „Tanzen mit einem Tamburin“ macht uns nur stärker, aber ich möchte immer noch eine sofort einsatzbereite Lösung.
Nach unserer Erfahrung können wir sagen, dass solche Probleme heutzutage nicht mehr so häufig sind, obwohl Drag & Drop überall verwendet wird. Wahrscheinlich ist die Wahl der Entwicklungstechnologien für Webanwendungen von Bedeutung. Der Prozentsatz der Anwendungen, die HTML5 verwenden, wächst jedoch stetig, Frameworks entwickeln sich und es wäre großartig, wenn die Entwickler von Browsern und Treibern für sie nicht zurückbleiben würden.
PS Und zum Schluss noch ein paar Texte. Ich möchte jedem raten, wenn möglich, die Banalität der Situation oder die Nähe der Testumgebung zu einem bestimmten Muster bei der Analyse von Problemen nicht zu berücksichtigen. Dies kann zu falschen Schlussfolgerungen oder Zeitverlust führen.