Supercharged-Testtipps für 2019: Ein Tutorial zum Testen der Java-Automatisierung
Veröffentlicht: 2022-03-11Jedes Jahr werden Testautomatisierungsingenieure aus der ganzen Welt die neuesten Tools und Techniken erforschen, um ihr Testautomatisierungs-Framework stabiler, schneller und benutzerfreundlicher und wartungsfreundlicher zu machen. Dies ist von entscheidender Bedeutung, um sicherzustellen, dass ihr Framework in ihrem Unternehmen weiterhin weit verbreitet ist. Generell kommen aufgeblähte, veraltete Frameworks schnell aus der Mode.
In diesem Artikel werfen wir einen Blick auf einige Möglichkeiten, wie Sie Ihr Framework für 2019 aktualisieren und sich auf 2020 vorbereiten können. Um mein Framework zu verbessern, konzentriere ich mich immer auf die „Schmerzpunkte“. Dies sind die Bereiche, die komplex einzurichten sind oder die meisten Fehler verursachen. Ich habe drei Hauptbereiche identifiziert, die ich vereinfachen oder verbessern wollte:
- Selen-Gitter
- Wartet
- Chrome-Entwicklungstools
Selenium Grid ist notorisch schwierig einzurichten und kann ohne Vorwarnung fehlschlagen. Ich wollte sehen, was sich hier, wenn überhaupt, verbessert hatte. Ich wollte auch untersuchen, ob der Selenium-API neue waits
hinzugefügt wurden, um die Stabilität der von mir erstellten Tests zu verbessern. Schließlich wollte ich sehen, ob ich mit der Interaktion mit Chrome DevTools über Selenium beginnen könnte, die zu einem wesentlichen Bestandteil des Toolkits eines jeden Testers geworden sind.
Tipp Nr. 1: Dockerisieren Sie Ihr Selenium Grid
Selenium Grid ist notorisch schwer einzurichten, instabil und in einer CI-Pipeline weder bereitzustellen noch Versionskontrolle zu betreiben. Ein viel einfacherer, stabiler und wartbarer Weg ist die Verwendung der vorgefertigten Selenium-Docker-Images.
Hinweis: Der einzige Nachteil dieser Methode ist, dass IE (Internet Explorer) nicht unterstützt wird, da es noch nicht möglich ist, das Windows-Betriebssystem zu containerisieren.
Einrichten
Um loslegen zu können, müssen Sie zunächst Docker und Docker Compose auf Ihrem Computer installieren. Wenn Sie Windows 10 oder einen Mac ausführen, werden beide über den Docker-Desktop installiert.
Starten Sie Ihr Raster
Das offizielle Selenium-Repository auf Docker Hub enthält vorgefertigte Docker-Images für Ihren Selenium Hub sowie Firefox- und Chrome-Knoten.
Die einfachste Möglichkeit, diese in einem lokalen Selenium Grid zu verwenden, besteht darin, eine Docker Compose-Datei im Stammverzeichnis Ihres Projekts zu erstellen. Benennen Sie die Datei docker-compose.yml
, um die Dinge einfach zu halten.
Ich habe unten ein Beispiel eingefügt, das das folgende Raster erstellt:
- Ein einzelner Selenium-Hub
- Ein Chrome-Knoten
- Ein Firefox-Knoten
#docker-compose.yml version: "3" services: selenium-hub: image: selenium/hub:3.141.59-neon container_name: selenium-hub ports: - "4444:4444" chrome: image: selenium/node-chrome:3.141.59-neon volumes: - /dev/shm:/dev/shm depends_on: - selenium-hub environment: - HUB_HOST=selenium-hub - HUB_PORT=4444 firefox: image: selenium/node-firefox:3.141.59-neon volumes: - /dev/shm:/dev/shm depends_on: - selenium-hub environment: - HUB_HOST=selenium-hub - HUB_PORT=4444
Die Docker Compose-Datei beschreibt die Einrichtung Ihres Grids. Weitere Informationen zum Erstellen von Docker Compose-Dateien finden Sie in der offiziellen Dokumentation.
Um Ihr Grid zu starten, verwenden Sie einfach ein beliebiges Terminalfenster (ein powershell
oder cmd
-Fenster in Windows), um den folgenden Befehl aus dem Stammverzeichnis Ihres Projekts auszuführen:
docker-compose up
Verbindung zum Netz
Sie können sich wie gewohnt mit Ihrem Selenium Grid verbinden, da der Hub auf Port 4444 Ihres lokalen Rechners lauscht. Hier ist ein Beispiel, in dem wir unseren Treiber so einrichten, dass er unseren Chrome-Knoten verwendet.
// Driver.java protected static RemoteWebDriver browser; DesiredCapabilities cap = new DesiredCapabilities(); ChromeOptions chromeOptions = new ChromeOptions(); cap.setCapability(ChromeOptions.CAPABILITY, chromeOptions); cap.setBrowserName("chrome"); driver = new RemoteWebDriver(cap);
Sie können dann die TestNG-Bibliothek verwenden, um Ihre Tests wie gewohnt auf mehreren Knoten parallel auszuführen.
Es ist erwähnenswert, dass auf jedem Knoten mehrere Browser ausgeführt werden können. Davon wird jedoch abgeraten, und die Verwendung eines Browsers pro Knoten gilt als bewährte Methode für eine optimale Leistung.
Zusätzliche Tipps und Tricks
Wenn Sie sehen möchten, was im Browser passiert, damit Sie Ihre Tests debuggen können, lohnt es sich, eine debug
-Version Ihrer docker-compose.yml
Datei zu haben, die die debug
-Browser-Knoten herunterlädt. Diese enthalten einen VNC-Server, sodass Sie den Browser beim Testlauf beobachten können.
Es ist auch möglich, die Browser kopflos auszuführen, um die Geschwindigkeit zu erhöhen (auf die übliche Weise), und Selenium bietet auch base
der Bilder, sodass Sie Ihre eigenen Bilder erstellen können, wenn Sie zusätzliche Software installieren müssen.
Um eine stabile Version des Grids für Ihre CI-Pipeline zu erstellen, ist es auch möglich, Ihr Grid auf Kubernetes oder Swarm bereitzustellen. Dadurch wird sichergestellt, dass alle Docker schnell wiederhergestellt oder ersetzt werden, wenn sie ausfallen.
Tipp Nr. 2: Kluges Warten
Wie jeder Testautomatisierungsingenieur weiß, sind waits
entscheidend für die Stabilität Ihres Testautomatisierungs-Frameworks. Sie können Ihren Test auch beschleunigen, indem sie alle sleeps
oder pauses
überflüssig machen und langsame Netzwerk- und Cross-Browser-Probleme überwinden. Im Folgenden finden Sie einige Tipps, um Ihre waits
noch widerstandsfähiger zu machen.
Java Automation Testing Tutorial Nr. 2: Logische Operatoren in Wartezeiten: Seien Sie spezifisch bei Ihren Wartezeiten
Die Klasse ExpectedConditions
ist im Laufe der Zeit gewachsen und umfasst nun fast jede erdenkliche Situation. Während ExpectedConditions.presenceOfElementLocated(locator)
“ oft ausreicht, empfiehlt es sich, die Methoden innerhalb der „ ExpectedCondition
“-Klasse zu verwenden, um jede Benutzeraktion abzudecken, indem Sie sie in Ihre Actions.java
-Klasse einbetten. Dadurch werden Ihre Tests gegen die meisten Cross-Browser- oder langsamen Website-Probleme kugelsicher.
Wenn beispielsweise das Klicken auf einen Link dazu führt, dass ein neuer Tab geöffnet wird, verwenden Sie ExpectedConditions.numberOfWindowsToBe(2)
. Dadurch wird sichergestellt, dass die Registerkarte vorhanden ist, bevor Sie versuchen, zu ihr zu wechseln.
Sie können auch ein wait
verwenden, um sicherzustellen, dass Sie alle auf der Seite vorhandenen Elemente erfassen, wenn findElements
verwenden. Dies kann besonders nützlich sein, wenn es einige Zeit dauert, bis eine search
ihre Ergebnisse zurückgibt. Zum Beispiel diese Zeile:
List<WebElement> results = driver.findElements(locators.RESULTS);
Dies kann zu einem leeren List
führen, wenn Ihre Suchergebnisse noch nicht geladen wurden. Stattdessen ist es besser, die erwartete Bedingung numberOfElementsToBeMoreThan
zu verwenden, um darauf zu warten, dass die Ergebnisse größer als null sind. Zum Beispiel:
WebElement searchButton = driver.findElement(locators.SEARCH_BUTTON); searchButton.click(); new WebDriverWait(driver, 30) .until(ExpectedConditions .numberOfElementsToBeMoreThan(locators.RESULTS, 0)); List<WebElement> results = driver.findElements(locators.RESULTS); results.get(0).click();
Jetzt wird Ihr findElements
Befehl nur ausgeführt, nachdem die Suchergebnisse zurückgegeben wurden.
Diese wait
ist auch nützlich, um einzelne Elemente zu finden, wenn Sie es mit einem Frontend zu tun haben, das nicht gut mit Selenium funktioniert (z. B. Angular-Websites). Das Erstellen einer solchen Methode schützt Ihre Tests und macht sie viel stabiler.
protected static WebElement waitForElement(By locator){ try { new WebDriverWait(browser, 30) .until(ExpectedConditions .numberOfElementsToBeMoreThan(locator, 0)); } catch (TimeoutException e){ e.printStackTrace(); Assert.fail("Timeout: The element couldn't be found in " + WAIT + " seconds!"); } catch (Exception e){ e.printStackTrace(); Assert.fail("Something went wrong!"); } return browser.findElement(locator); }
Es ist sogar möglich zu warten, bis Elemente nicht mehr sichtbar sind. Dies ist besonders nützlich, wenn Sie darauf warten, dass ein Popup verschwindet, nachdem Sie auf die Schaltfläche „ OK
“ oder „ Save
“ geklickt haben, bevor Sie mit dem Test fortfahren.
WebElement okButton = driver.findElement(locators.OK_BUTTON); okButton.click(); new WebDriverWait(driver, 30) .until( ExpectedConditions .invisibilityOfElementLocated(locators.POPUP_TITLE) );
Alle oben beschriebenen Methoden und mehr sind in der offiziellen Dokumentation aufgeführt. Es lohnt sich, zehn Minuten damit zu verbringen, alle Möglichkeiten durchzulesen und die Stabilität Ihres Frameworks zu verbessern.
Java Automation Testing Tutorial Nr. 2: Logische Operatoren in Wartezeiten
Eine gute Möglichkeit, Ihre waits
widerstandsfähiger zu machen, ist die Verwendung logischer Operatoren. Wenn Sie beispielsweise überprüfen möchten, ob ein Element gefunden wurde UND ob es anklickbar ist, würden Sie den folgenden Code verwenden (bitte beachten Sie, dass diese Beispiele einen booleschen Wert zurückgeben):
wait.until(ExpectedConditions.and( ExpectedConditions.presenceOfElementLocated(locator), ExpectedConditions.elementToBeClickable(locator) ) );
Der ODER-Operator wäre angebracht, wenn Sie sich nicht sicher sind, ob sich der Titel der Seite ändern könnte oder nicht. Dann können Sie eine Prüfung der URL einschließen, wenn die erste Bedingung fehlschlägt, um zu bestätigen, dass Sie sich definitiv auf der richtigen Seite befinden.

wait.until(ExpectedConditions.or( ExpectedConditions.titleIs(expectedTitle), ExpectedConditions.urlToBe(expectedUrl) ) );
Oder wenn Sie sicherstellen möchten, dass ein Kontrollkästchen nicht mehr aktiviert ist, nachdem eine Aktion auf der Seite ausgeführt wurde, ist der NOT-Operator geeignet.
wait.until(ExpectedConditions.not( ExpectedConditions.elementToBeClickable(locator) ) );
Die Verwendung von Operatoren kann Ihre waits
widerstandsfähiger machen und zu Tests führen, die weniger spröde sind.
Tipp Nr. 3: Chrome DevTools: Simulieren von Netzwerkbedingungen
Das Ausführen Ihrer Web-App auf localhost oder in einem lokalen Netzwerk kann einen falschen Eindruck von ihrer Leistung erwecken, wenn sie in freier Wildbahn ausgeführt wird. Die Möglichkeit, verschiedene Upload- und Download-Geschwindigkeiten zu drosseln, gibt Ihnen eine bessere Vorstellung davon, wie Ihre Anwendung über das Internet ausgeführt wird, wo Zeitüberschreitungen dazu führen können, dass Aktionen fehlschlagen. Wir können damit beginnen, dies mit der Leistungsfähigkeit der DevTools von Chrome zu simulieren.
Der folgende Code öffnet die Toptal-Startseite mit unterschiedlichen Download- und Upload-Geschwindigkeiten. Zuerst speichern wir unsere Geschwindigkeiten in einem TestNG-Datenanbieter mit dem folgenden Code:
import org.testng.annotations.DataProvider; public class ExcelDataProvider { @DataProvider(name = "networkConditions") public static Object[][] networkConditions() throws Exception { return new Object[][] { // Upload Speed, Dowload Speed in kb/s and latency in ms. { 5000 , 5000, 5 }, { 10000, 7000, 5 }, { 15000, 9000, 5 }, { 20000, 10000, 5 }, { 0, 0 }, }; } }
Hinweis: Die Upload- und Download-Drosselung wird in kb/s
und die Latenz in ms
.
Dann können wir diese Daten verwenden, um unseren Test unter verschiedenen Netzwerkbedingungen durchzuführen. Innerhalb des Tests führt der CommandExecutor
den Befehl in der aktuellen Sitzung des Browsers aus. Dadurch werden wiederum die erforderlichen Einstellungen in den Chrome-Entwicklertools aktiviert, um unser langsames Netzwerk zu simulieren. Der Code in der if
-Anweisung kann in eine @BeforeClass
Methode eingefügt werden, wenn eine Reihe von Tests ausgeführt wird.
import org.testng.annotations.Test; import com.google.common.collect.ImmutableMap; import java.io.IOException; import java.util.HashMap; import java.util.Map; import org.openqa.selenium.remote.Command; import org.openqa.selenium.remote.CommandExecutor; import org.openqa.selenium.remote.Response; public class TestClass { // load our data provider @Test(dataProvider = "networkConditions") public void test(int download, int upload, int latency) throws IOException { // only run if the network is throttled if (download > 0 && upload > 0) { CommandExecutor executor = driver.getCommandExecutor(); // create a hashmap of the required network conditions Map map = new HashMap(); // you can even test 'offline' behaviour map.put("offline", false); map.put("latency", latency); map.put("download_throughput", downloadThroughput); map.put("upload_throughput", uploadThroughput); // execute our code Response response = executor.execute( new Command(driver.getSessionId(), "setNetworkConditions", ImmutableMap.of("network_conditions", ImmutableMap.copyOf(map)))); } // Open the website driver.get("https://www.toptal.com/"); // You can then check that elements are loaded etc. // Don't forget to use waits! } }
Bonus-Tipp: So verwalten Sie Ihre Cookies
Browser-Cookies können unterschiedliche Verhaltensweisen in Ihrer Anwendung bewirken, je nachdem, ob sie von einer früheren Sitzung gespeichert wurden oder nicht (z. B. könnte die Anwendung mit einem bereits angemeldeten Benutzer geladen werden). Es empfiehlt sich, Ihre Cookies vor jedem Testlauf zu löschen, um sicherzustellen, dass sie keine Probleme verursachen.
Mit dem folgenden Code können Sie alle Ihre Cookies löschen:
driver.manage().deleteAllCookies();
Sie können ein Cookie auch nach Namen löschen:
driver.manage().deleteCookieNamed("CookieName");
Oder erhalten Sie den Inhalt eines Cookies:
String myCookie = driver.manage().getCookieNamed("CookieName").getValue();
Oder holen Sie sich alle Kekse:
List<Cookie> cookies = driver.manage().getCookies();
Testautomatisierung im Jahr 2020: Blick in die Zukunft
Selenium 4 wird in den nächsten Monaten veröffentlicht. Es befindet sich noch in der Entwicklung, aber da bereits eine Alpha-Version veröffentlicht wurde, lohnt es sich, einen Blick darauf zu werfen, welche Verbesserungen es bieten wird.
Hinweis: Sie können ihren Fortschritt verfolgen, indem Sie sich die Roadmap ansehen.
W3C WebDriver-Standardisierung
Selenium muss nicht mehr über das JSON-Drahtprotokoll mit dem Browser kommunizieren; Stattdessen kommunizieren automatisierte Tests direkt mit dem Browser. Dies sollte die berühmte schuppige Natur von Selenium-Tests ansprechen, einschließlich des Schutzes vor Browser-Upgrades. Hoffentlich erhöht sich auch die Testgeschwindigkeit.
Ein einfacheres Selengitter
Das Selenium Grid wird in Selenium 4 stabiler und einfacher einzurichten und zu verwalten sein. Benutzer müssen Hubs und Knoten nicht mehr separat einrichten und starten, da das Grid als kombinierter Knoten und Hub fungiert. Außerdem wird es eine bessere Unterstützung für Docker geben, parallele Tests werden nativ enthalten sein und es wird eine informativere Benutzeroberfläche bieten. Request Tracing mit Hooks hilft Ihnen auch beim Debuggen Ihres Grids.
Dokumentation
Die Selenium-Dokumentation wird dringend überarbeitet, da sie seit der Veröffentlichung von Selenium 2.0 nicht aktualisiert wurde.
Änderungen an der API
Die Unterstützung für die Browser Opera und PhantomJS wird entfernt. Headless Running kann mit Chrome oder Firefox durchgeführt werden, und Opera basiert auf Chromium, weshalb Chromium-Tests für diesen Browser als ausreichend angesehen werden.
WebElement.getSize()
und WebElement.getLocation()
werden jetzt durch eine einzelne Methode WebElement.getRect()
ersetzt. Da diese jedoch häufig zum Erstellen von Screenshots eines einzelnen Elements verwendet werden, sollten Sie wissen, dass es in Selenium 4 auch einen API-Befehl zum Erfassen eines Screenshots eines Elements geben wird.
Für WebDriver Window
werden die Methoden getPosition
und getSize
durch die Methode getRect
und die Methoden setPosition
und setSize
durch die Methode setRect
ersetzt. fullscreen
und minimize
sind verfügbar, sodass diese Aktionen innerhalb Ihres Tests ausgeführt werden können.
Andere bemerkenswerte Änderungen:
- Die
Options
-Klasse für jeden Browser erweitert nun dieCapabilities
-Klasse. - Eine
driver.switchTo().parentFrame()
wurde hinzugefügt, um die Frame-Navigation zu vereinfachen. - Es werden
nice
Ortungsgeräte hinzugefügt, die auf einer höheren Ebene als die aktuellen arbeiten. Sie werden eine Unterklasse vonBy
sein. - Es wird eine Implementierung der
DevTools
API geben, die es Benutzern ermöglicht, Funktionen zu nutzen, die durch die Verwendung des Chrome-Debugging-Protokolls (und Äquivalenten in anderen Browsern) angeboten werden. Diese schließen ein:- Ganzseitige Screenshots (einschließlich Offscreen-Elemente).
- Streaming-Protokolle.
- Warten auf Mutationsereignisse auf der Seite.
- Viele veraltete Methoden und Klassen werden ebenfalls gelöscht.
Hinweis: Sie können eine Alpha-Version von Selenium 4 aus dem Maven-Repository beziehen. Es wird dringend empfohlen, dies mit Ihrem aktuellen Framework (idealerweise in einem Sandbox-Zweig) auszuprobieren, damit Sie für die Änderung bereit sind.
Fazit
In diesem Artikel habe ich einige Bereiche behandelt, in denen ich mein Testautomatisierungs-Framework zum Besseren verbessert habe. Es ist jetzt stabiler und benutzerfreundlicher als zuvor, was sich positiv auf alle am Softwarebereitstellungslebenszyklus Beteiligten auswirken wird.
Die oben skizzierten Änderungen vorzunehmen ist ein guter Anfang, ich empfehle Ihnen jedoch dringend, Ihr gesamtes Framework auf „Schmerzpunkte“ zu überprüfen, da Sie möglicherweise Verbesserungen vornehmen können, die ich nicht behandelt habe. Verwenden Sie beispielsweise WebDriver Manager, um Ihre Treiber zu verwalten, oder aktualisieren Sie sie immer noch manuell?
Ich würde auch empfehlen, mindestens einmal im Jahr einen Termin festzulegen, idealerweise jedoch alle sechs Monate. In den Artikel habe ich die Änderungen aufgenommen, die in Selenium 4.0 kommen. Bitte sehen Sie sich die alpha
-Versionen von Selenium selbst an. Die Veränderungen werden dramatisch sein und Sie müssen vorbereitet sein. Ich hoffe, Sie fanden das nützlich. Wenn Sie beim Frühjahrsputz Ihres Frameworks neue Methoden oder Techniken entdecken, teilen Sie diese bitte mit anderen Lesern dieses Blogs, indem Sie sie dem Kommentarbereich unten hinzufügen.
Wenn Sie außerdem einen Blick auf automatisierte Tests in Selenium werfen möchten und erfahren möchten, wie Sie Seitenobjektmodelle verwenden können, um wartbare und wiederverwendbare Testroutinen zu schreiben, sehen Sie sich Automatisierung in Selenium: Seitenobjektmodell und Seitenfabrik an .