GUI-Tests mit Selenium
Selenium ist ein Open Source Werkzeug zur Automatisierung von Browser-Applikationen.
Es zählt seit vielen Jahren zu den bekanntesten und beliebtesten UI Testautomatisierungslösungen für Webanwendungen.
In erster Linie ist Selenium für die Automatisierung von Webanwendungen zu Testzwecken gedacht, kann jedoch auch für weitere, operative Aufgaben sinnvoll eingesetzt werden.
So können mittels Selenium viele sich wiederholende Aufgaben bei der Administration webbasierter Anwendungen automatisiert werden.
Ebenfalls findet Selenium immer stärkeren Einsatz bei Automatisierung der komplexen operativen Geschäftsprozesse mittels „Robotic Process Automation“ (RPA) Lösungen.
1. Setup
Zum Aufsetzen von Selenium und dem Erstellen von webbasierten GUI-Tests mit Selenium, sollte die ausführliche Entwickler-Dokumentation von Selenium herangezogen werden:
1.1. Selenium installieren
In Maven: selenium-java dependency in die pom.xml einfügen:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>${selenium.version}</version>
<scope>test</scope>
</dependency>
In Gradle: selenium-java dependency in die build.gradle des Projektes einfügen:
dependencies {
compile group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '4.0.0'
1.2. Browser Drivers installieren
Die Browser Driver zur Unterstützung der Browser für Selenium werden von den jeweiligen Herstellern entwickelt und sind nicht Teil der Standard Selenium Distribution.
Empfohlen wird an dieser Stelle der Firefox Browser:
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-firefox-driver</artifactId>
<version>${selenium.version}</version>
<scope>test</scope>
</dependency>
1.3. Browser öffnen und schließen
|
Selenium 4 benötigt die Firefox Version 78 oder höher! |
// create custom Firefox options
FirefoxOptions options = new FirefoxOptions();
// open Browser
WebDriver driver = new FirefoxDriver(options);
// close Brower
driver.quit();
2. Problematiken
Trotz der Beliebtheit bei UI Testautomatisierungslösungen für Webanwendungen ist Selenium kein vollwertiges Test-Framework!
Das zeigt sich in folgenden Dimensionen:
2.1. Testen
-
Seleniumstellt keine Assertions bereit, sondern kümmert sich um die reine UI-Automatisierung -
Seleniumliefert keine Integration in JUnit -
Die Testkonfiguration kann komplex sein
2.2. Allgemein
-
Seleniumist ein DOM basiertes (Java-) Interface zum Browser. Daher ist ein Verständnis vonHTML/CSSerforderlich, um automatisierte Abläufe zu beschreiben -
In
Seleniumwerden nur Referenzen von DOM Elementen gehalten, nichts wird zwischen gespeichert -
Seleniumadressiert die Asynchronität des Browsers nur oberflächlich
3. Best Practices
Zu den oben genannten Problemen gibt es Best Practices, mit denen man diesen entgegen wirken kann.
3.1. Assertions
Assertions mit Selenium sind für WebElement-Typen erstmal nicht möglich.
Allerdings lassen sich die Values oder andere inhaltliche Werte und ihre primitiven Datentypen mittels Standard Assertions vergleichen:
import org.junit.Assert;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDrive
[...]
@Test
public void testAssertFunctions() {
// Driver setup
System.setProperty("webdriver.chrome.driver", {$uri-to-driver}\\chromedriver.exe");
WebDriver driver = new ChromeDriver();
// Driver navigation
driver.navigate().to("https://www.url.com/");
String ActualTitle = driver.getTitle(); // returns the titel as a String
String ExpectedTitle = "Most Reliable App & Cross Browser Testing Platform | BrowserStack";
// String assertions
Assert.assertEquals(ExpectedTitle, ActualTitle);
// Get web element checkbox
WebElement checkbox = driver.findElement(By.cssSelector("input[id*='StayLoggedInCheckbox']"));
// Boolean assertions
Assert.assertFalse(checkbox.isSelected());
// isSelected returns primitive datatype boolean which we can assert
// close browser
driver.quit();
}
3.2. WebElement Finding bei asynchronen Änderungen
Grundlegende Informationen, wie man WebElemente über Selenium findet:
Sollten Probleme bei der Suche nach WebElement-Ids entstehen (z.B. da diese dynamisch generiert werden), kann auf zwei alternative Möglichkeiten zurückgegriffen werden:
3.2.1. XPath
XPath ist eine Alternative zum WebElement-Finding per ID.
Es handelt sich dabei um die XML Path Language, die Teile eines XML-Dokumentes adressieren und auswerten kann.
Da HTML und XML eine ähnliche Struktur haben, fällt es Selenium leicht, bei statischem HTML-Aufbau ein Web-Element über XPath zu finden.
WebElement checkbox = driver.findElement(
By.xpath("/html/body/div[2]/div[1]/div/h4[1]/b/html[1]/body[1]/div[2]/div[1]/div[1]/h4[1]/b[1]"));
Aber auch die XPath-Pfade können durch die Asynchronität des Browsers oder durch dynamische Generierung ihr Ziel verfehlen.
3.2.2. Css Selector
Etwas sicherer und eventuell beständiger ist der Css Selector. Beispiel:
<input id="name"...>
wird generiert zu:
<input id="j_id1234567:name"...>
Die Suche nach dem WebElement mittels Selenium würde dann wie folgt aussehen:
driver.findElement(By.cssSelector("input[id^='j_id'][id$='name']"));
Das bedingt natürlich, dass die dynamischen IDs wenigstens zum Teil statisch sind, bzw. statische Komponenten wie bspw. name beinhalten.