Das Testen langer Webformulare in verschiedenen Browsern und in Auflösungen ist nicht nur äußerst notwendig, sondern auch zum dritten oder vierten Mal - ein äußerst langweiliger und konzentrationsintensiver Prozess. Dies ist also genau der Bereich, der selbst nach Automatisierung verlangt. Das haben wir getan.
In diesem Artikel über Habr berichten wir über unsere Erfahrungen beim Testen von Großbildschirmen mit Winkelmesser-, Zalenium- und Selen-Gitterwerkzeugen. Wie wir diese Tools schrittweise für automatische UI-Tests eingeführt haben und welche Schwierigkeiten wir hatten.

Wir erstellen und pflegen ein System mit 7.000 aktiven Benutzern. Am häufigsten verwenden sie diese Browser:

Und die folgenden Bildschirmauflösungen:

Jedes Mal nach der Veröffentlichung einer neuen Version müssen Sie die Leistung dieser Browser und Berechtigungen überprüfen.
Betrachten Sie einen einfachen Fall, um besser zu verstehen, wie UI-Tests in unserem Fall normalerweise funktionieren: Testen der Funktionalität einer Kennwortwiederherstellungsanwendung. Dementsprechend gibt es zwei Seiten. Zum einen müssen Sie einen Benutzernamen oder eine E-Mail-Adresse angeben, in der ein Brief mit einem Link zu einer Kennwortänderung enthalten ist. Nach dem Senden der Anwendung geht der Benutzer auf die Seite mit der Bestätigung, dass alles gut gelaufen ist.
Passwortwiederherstellungsformular
Die Seite, auf die die Weiterleitung nach erfolgreicher Einreichung des Antrags erfolgtDas Testen dieses Mechanismus in vereinfachter Form sieht folgendermaßen aus:

Das gleiche Skript wie Code:
it(' ', async function(): Promise<boolean | void> { await browser.get(browser.baseUrl); await element(by.name('EmailOrLogin')).sendKeys(userLogin); await element(by.buttonText('')).click(); const screenshot = await browser.takeScreenshot(); const canonicalScreenshotPath = < >; await compareScreenshot(screenshot, canonicalScreenshotPath); });
Wie Sie sehen können, sieht der Testcode recht einfach aus und wiederholt buchstäblich das, was im Blockdiagramm gezeigt wurde.
Jetzt zeigen wir, welche Tools sich als nützlich erwiesen haben, um dieses Schema bei verschiedenen Bildschirmauflösungen zu implementieren, und auf welche Schwierigkeiten wir gestoßen sind.
Ausgewählte Toolbox
Begonnen mit Chrom
Für die Testautomatisierung haben wir Protractor gewählt, ein e2e-Framework zum Testen von Angular-Anwendungen. Unsere Anwendung ist nur auf Angular. Mit Protractor haben wir zwei Arten von Tests durchgeführt:
- Zur allgemeinen Funktionalität: Ein Antragsformular wird geöffnet, mit Daten ausgefüllt und ein Antrag gesendet. Anschließend überprüfen wir, ob eine Umleitung zur Registrierung aller Anträge erfolgt ist.
- Screenshot-Tests: Mit dem Winkelmesser können Sie jederzeit einen Screenshot erstellen. Mit einer separaten Blue-Harvest-Bibliothek haben wir zwei Screenshots verglichen: eine Referenz und eine echte. Wenn sie nicht übereinstimmen, wird sofort ein Screenshot erstellt, auf dem alle Unterschiede sichtbar sind, genau wie in Git.
Wenn Sie beispielsweise das oben beschriebene Beispiel weiter analysieren.
Screenshot mit ungültiger Linkmeldung
Die Unterschiede (Text und Layout der Schaltfläche) in den Referenz- und aktuellen Screenshots sind lila hervorgehobenWenn die Seite sich dynamisch ändernde Daten enthält (z. B. Datum oder Bestellnummer), müssen Sie diese maskieren. Diese Funktionen befinden sich in der Blue-Harvest-Bibliothek. Andernfalls führt ein Vergleich der Screenshots zu einem negativen Ergebnis.
Fügen Sie FF und verschiedene Berechtigungen hinzu
Im Laufe der Zeit sind unsere Anforderungen an das vorhandene UI-Testsystem gestiegen:
- Führen Sie Tests nicht nur in Chrome, sondern auch in FF durch.
- Screenshot-Tests nicht mit einer, sondern mit den beliebtesten Auflösungen durchführen.
- Führen Sie Tests parallel durch.
Lassen Sie uns also unsere Tests in Chrome und FF parallel ausführen.
Ersetzen Sie dazu in der Protractor'a-Funktionskonfiguration Folgendes:
multiCapabilities: [ { shardTestFiles: true, maxInstances: 2, browserName: 'chrome' }, { shardTestFiles: true, maxInstances: 2, browserName: 'firefox' } ]
Hier ist alles offensichtlich, wofür jede Einstellung verantwortlich ist. Verdient nur Aufmerksamkeit
shardTestFiles: true
/** * If this is set to be true, specs will be shared by file (ie all files to be run by this set of capabilities will run in parallel). * Default is false. */
Mit diesem Flag können alle Spezifikationen in allen Browsern, die in multiCapabilities angegeben sind, parallel gestartet werden.
Der Parameter specs ist unter den Wortspezifikationen verborgen, die bestimmen, anhand welcher Vorlage nach Dateien mit Tests gesucht werden soll.
exports.config = { ... specs: ['./e2e/**/*.spec.ts'], ... }
Die Theorie, alle Tests in mehrere Spezifikationsdateien aufzuteilen, sieht ziemlich logisch aus. Parallelität funktioniert auf ihnen (erstellen Sie beispielsweise eine Spezifikationsdatei für jede Funktion der Anwendung).
Darüber hinaus gibt es in Protractor'e die Möglichkeit, Suiten hervorzuheben.
exports.config = { ... suites: { suite01: './e2e/**/suite01.*.spec.ts', suite02: './e2e/**/suite02.spec.ts', suite03: './e2e/**/suite03.spec.ts' }, ... }
Wie Sie in diesem Teil der Konfiguration sehen können, werden beim Starten einer Suite Tests nur von einer Spezifikationsdatei ausgeführt. Dies ist wahrscheinlich nützlich, wenn Sie Tests nur für einen Teil der Anwendung ausführen möchten.
Beim Testen der Anwendung mit verschiedenen Auflösungen haben wir den folgenden Weg eingeschlagen. Als experimentelle Berechtigung wurde eine der beliebtesten ausgewählt: 1920 x 1080, 1366 x 768, 1440 x 10900, 768 x 1024. Wenn Sie jeden Test ausführen, wurden zunächst alle erforderlichen Aktionen ausgeführt, und anschließend werden eine Reihe von Screenshot-Überprüfungen durchgeführt.

Wir verbinden IE und Screenshots in voller Größe
Die Screenshot-Tests, die wir leider erhalten haben, haben nur auf der Grundlage des anfangs sichtbaren Teils der Seite funktioniert. Und wenn auf der Seite ein Bildlauf vorhanden war, blieb alles unten für das Layout unerforscht.
Darüber hinaus müssen wir auch den IE unterstützen, für den unsere Tests noch nicht entwickelt wurden. Wir suchten nach einer geeigneten Möglichkeit, Tests im Internet Explorer durchzuführen und Screenshots in voller Größe zu erstellen.

Wir haben uns für zwei Lösungen entschieden:
Zalenium und
Selenium-Grid . Wir lassen die Beschreibung weg, welche von ihnen sich von was rühmt, und erzählen, was sie in beiden Lösungen gefunden / nicht gefunden haben.
Zalenium : Diese Lösung wird in einem Docker-Container ausgeführt, und N andere Container steigen nach dem
Hauptcontainer auf, um Browser zu starten. Ermöglicht die Angabe von screenWidth und screenHeight während des
docker run
und das Abrufen der Bildschirmgröße, z. B. 1920 x 6000. Es gibt keine Unterstützung für IE.
Zwei Browser mit einer Bildschirmgröße von 1920x6000Selen-Gitter: Tests im IE begannen sehr einfach.
Von den Minuspunkten: Es gibt keine Möglichkeit, die Größe des Browserfensters beliebiger Größe festzulegen.
Gesamt: Zalenium + Selen-GitterWir haben uns für eine Reihe von Zalenium + Selen-Gittern entschieden: Durch Zalenium wurde beschlossen, Tests in Chrome und FF durchzuführen, und durch Selenium-Gitter, um die Mindestleistung der Anwendung im IE zu überprüfen.
Was war interessant dabei zu treffen
1. Verwenden von formControlName als Element-LocatorMit der Suche in formControlName können Sie einfach nach den erforderlichen Feldern im Formular suchen und diese mit Testdaten füllen. Der Locator von formControlName ist nicht integriert, kann aber einfach hinzugefügt werden:
exports.config = { ... onPrepare() { require('ts-node').register({ project: 'e2e/tsconfig.e2e.json' }); jasmine.getEnv().addReporter(new specReporter({ spec: { displayStacktrace: true } })); addFormControlNameLocator(protractor); } ... } function addFormControlNameLocator(protractor) { protractor.by.addLocator('formControlName', function(value, optParentElement) { var using = optParentElement || document; return using.querySelectorAll('[formControlName="' + value + '"]'); }); }
2. Der Unterschied in der Arbeit des global und lokal installierten Webdriver-Managers in ProtractorBei der Installation von Protractor im System (in der offiziellen Dokumentation wird empfohlen, Protractor global zu installieren) erhalten wir zusätzlich zum Testframework selbst den installierten Webdriver-Manager, der Treiber für Browser bereitstellt, um Tests auszuführen, bei denen eines der Probleme aufgetreten ist.
Nachdem Sie den Projektordner aufgerufen und das Webdriver-Manager-Update ausgeführt haben, werden Treiber für Chrome, FF, IE heruntergeladen. Danach haben sie beim Starten der Tests den Fehler festgestellt:
No update-config.json found. Run 'webdriver-manager update' to download binaries.
Wir haben festgestellt, dass der Fehler verschwindet, wenn wir das Webdriver-Manager-Update in ein npm-Skript packen:
{ ... scripts:{ “webdriver-update”: “webdriver-manager update” } ... }
npm run webdriver-update
, werden sowohl die
npm run webdriver-update
als auch die oben erwähnte Datei update-config.json in den Projektordner verschoben.
3. Führen Sie Zalenium durch Docker-Compose ausDie Zalenium-Dokumentation enthält Beispiele für den
docker run
und die Docker-Compose-Datei. Alles hebt fast wie durch Zauberei ab. Das einzige Problem, auf das wir gestoßen sind, ist beim Starten der Docker-Compose-Datei aufgetreten
/var/run/docker.sock is not a valid windows path
. Die Lösung ist
hier .
4. Sichtbarkeit der Elemente durch den WinkelmesserIm Verlauf unserer Experimente standen wir in einem Moment vor der Aufgabe, ein Menü auf der Seite zu durchstechen, d. H. Gehen Sie zu jeder Seite des Menüs und machen Sie einen Screenshot.

Nach der Verarbeitung des ersten Elements der Liste begannen die Tests zu fallen, was den Fehler auslöste, dass auf einige Koordinaten nichts zu klicken war. Wie sich herausstellte, verschwanden sie, unabhängig davon, dass alle Elemente der Liste ursprünglich ausgewählt wurden, nachdem sie für unsere Augen wirklich unsichtbar geworden waren, in den Augen des Winkelmessers.
Wir haben das Problem gelöst, indem wir eine ausreichende Bildschirmbreite eingestellt haben, damit das Menü wieder angezeigt wird, bevor Sie auf das nächste Element klicken.
5. Auflösungsänderung im IE (Selenium-Gitter)Wie Sie sich erinnern, haben wir in Chrome und FF die Änderung der Bildschirmauflösung optimiert. Als es dazu im IE kam, haben wir einfach den Fehler abgefangen:
Failed: java.io.IOException: Server returned HTTP response code: 405 for URL: http://localhost:21800/session/8d14426d-6483-4bbf-90b3-2a3ed46ebe9b/window/size
.
Nach einem langen Debugging konnte festgestellt werden, dass der Fehler genau in dem Moment
browser.driver.manage().window().setSize(x, y)
, in dem der Code ausgeführt werden soll:
browser.driver.manage().window().setSize(x, y)
. Wenn Sie versuchen,
browser.driver.manage().window().setPosition(x, y)
auszuführen, und denselben Fehler abfangen, ändert sich nur die Größe in die Position. Dies führt uns zu der Tatsache, dass es unmöglich ist, die Bildschirmauflösung zu steuern, wenn Tests im IE ausgeführt werden. Die Lösung des Problems sind Krücken, mit denen Sie Ihren Code überlagern müssen, um die Auflösung \ Position nicht zu ändern, wenn der IE ausgeführt wird.
6. Zalenium und WebSocketNachdem alle Unebenheiten vor Ort gesammelt worden waren, wurde beschlossen, Zalenium in die Unternehmensinfrastruktur aufzunehmen. Der Container wird geöffnet, DNS wird registriert, jetzt kann jeder Tests in Zalenium ausführen, indem er einfach den Pfad dazu in seiner Winkelmesser-Konfiguration angibt. Schönheit, nicht wahr? Aber da war es.
In diesem Fall wurde bereits alles auf dem Linux-Computer bereitgestellt, Nginx wurde als Server verwendet. Der Container mit Zalenium stieg ohne Probleme an, gefolgt von weiteren N Containern zum Starten von Browsern, aber ... konnte keine Verbindung zu ihnen herstellen. Es war leicht festzustellen, dass der übergeordnete Container versuchte, über das WebSocket-Protokoll mit den Containern der Browser zu kommunizieren, und Nginx konnte dies standardmäßig nicht tun. Die Behandlung ist sehr einfach.
location / { proxy_pass some_url; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection “upgrade”; }
9. Start des Selen-GridsUm Selen-Grid zu betreiben, benötigen wir:
- Selen-Server ,
- IE-Treiber, der über das Webdriver-Manager-Update --ie32 leicht zu bekommen ist.
Serverstart:
java -jar selenium-server-standalone.jar -role hub -hubConfig selenium-server-config.json
selenium-server-config.json { "host": "127.0.0.1", "maxSessions": 5, "port": 4445, "cleanupCycle": 5000, "timeout": 300000, "newSessionWaitTimeout": -1, "servlets": [], "prioritizer": null, "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher", "throwOnCapabilityNotPresent": true, "nodePolling": 180000, "platform": "WINDOWS" }
Starten des IE-Treibers:
java -Dwebdriver.ie.driver=< > -jar selenium-server-standalone.jar -role node -nodeConfig .\\ie-driver-config.json
ie-driver-config.json { "capabilities": [ { "browserName": "internet explorer", "maxInstances": 1, "platform": "WINDOWS", "webdriver.ie.driver": "C:/Program Files (x86)/Internet Explorer/iexplore.exe" } ], "cleanUpCycle": 2000, "timeout": 30000, "port": -1, "role": "node", "hub": "http://127.0.0.1:4445/grid/register/", "register": true, "maxSessions": 5 }
Achten Sie beim Starten des Servers und in der Hub-URL des Treibers auf die Verwendung derselben Ports. Als seleniumAddress in der Winkelmesserkonfiguration verwenden wir
http://127.0.0.1:4445/wd/hub
.
Schlussfolgerungen
Wir haben unsere Aufgabe gelöst und können jedes Mal nach der Veröffentlichung einer neuen Version die Leistung dieser Browser und Auflösungen überprüfen.
So integrieren Sie Tests in einen Workflow
Es ist wichtig zu verstehen, dass es nicht ausreicht, nur die gesamte Infrastruktur zu erhöhen, um Tests auszuführen und zu schreiben. Sie müssen darüber nachdenken, wie Sie sie in Ihrem täglichen Leben verwenden werden.
Wir haben keine UI-Tests in CI implementiert, weil Sie werden lange genug ausgeführt, damit sie bei jedem Build auf ihre Ausführung warten können.
Um die lokale Version der Anwendung zu testen oder in einer der Testumgebungen (intern oder vom Kunden) installiert zu haben, reicht es aus, baseUrl in der Protractor'a-Konfiguration zu ändern. Daher können Tests sowohl vom Entwickler als auch vom Tester ausgeführt werden.
Entwickler - Wenn Tests für die lokale Version der Anwendung ausgeführt werden müssen, während eine neue Funktion entwickelt wird. QS-Spezialist - zum Beispiel als Rauchtest nach dem Einsatz bei Prod oder als Kontrolle auf der Oberseite nach einem Refactoring-Haufen.
Abschließend möchten wir betonen:- Denken Sie daran, dass Sie durch UI-Tests keine detaillierten manuellen Tests durchführen müssen. Automatisierung hilft nur, Bereiche abzudecken.
- Verwenden Sie die Automatisierung mit Bedacht, vor allem für Rauchtests. Alles und jedes abzudecken macht keinen Sinn - es ist teuer und schwierig, auf dem Laufenden zu bleiben
- Schreiben Sie einfach. Wenn Ihre UI-Tests kompliziert aussehen, machen Sie etwas falsch. Einfach schlagen und wie angegeben verwenden (siehe Punkt 2)
Wir glauben, dass die Automatisierung von UI-Tests gut ist, wenn sie einfach durchgeführt werden kann. Teilen Sie uns daher Ihre Beobachtungen und erfolgreichen Tools in den Kommentaren mit.
Nützliche Links von uns: