Ein umfassender Leitfaden zum Testen von Authentifizierungsabläufen mit Selenium und der Yenlo Connext Platform
Selenium ist ein beliebtes automatisiertes Open-Source-Testframework, das häufig zum Testen von Webanwendungen verwendet wird. Es ermöglicht Testern das Schreiben und Ausführen von Testfällen in einer Vielzahl von Programmiersprachen, darunter Java, Python, Ruby und C#. Einer der Hauptvorteile von Selenium ist die Fähigkeit, echte Benutzerinteraktionen mit einer Webanwendung zu simulieren, was es zu einem wertvollen Werkzeug für das Testen des Authentifizierungsprozesses von Webanwendungen macht.
Unter Authentifizierung versteht man den Prozess der Identitätsüberprüfung eines Benutzers, die durch verschiedene Methoden wie Benutzername und Passwort, OAuth/OIDC und Single Sign-On (SSO) erfolgen kann. Mit Selenium können Tester den Prozess der An- und Abmeldung bei Webanwendungen automatisieren und die Funktionalität und Sicherheit des Authentifizierungsprozesses testen. Der Authentifizierungsprozess ist eine wichtige Komponente jeder Webanwendung, da er sicherstellt, dass nur autorisierte Benutzer Zugang zu sensiblen Informationen und Ressourcen haben. Das Testen dieses Prozesses ist ein wesentlicher Teil des Entwicklungsprozesses und erfordert ein umfassendes Verständnis der verschiedenen eingesetzten Technologien und Protokolle.
In diesem Blog erfahren Sie, wie Sie auf einfache Weise eine Testsuite erstellen können, um den Anmeldevorgang für Ihre Anwendungen zu testen.
Ich werde die Yenlo Connext Platform als Identitätsanbieter verwenden, der uns den Authentifizierungsdienst zur Verfügung stellt. Yenlo Connext isteine rund um die Uhr gehostete und verwaltete Cloud-Lösung basierend auf der WSO2-Technologie.
Bitte beachten Sie, dass dieses Testverfahren von Selenium die Authentifizierung testen kann, wenn keine Mehrfaktor-Authentifizierung wie E-Mail OTP/SMS OTP aktiviert ist. Auf der offiziellen Seite von Selenium wird auch empfohlen, die Basisauthentifizierung ohne Multifaktor-Authentifizierung zu testen.
Wie richte ich eine Testumgebung für das Testen der Authentifizierung von Webanwendungen ein?
Der erste Schritt beim Testen des Authentifizierungsprozesses einer Webanwendung besteht darin, die Testumgebung einzurichten. Dazu gehört in der Regel die Installation von Selenium sowie aller zusätzlichen Software oder Bibliotheken, die für die Interaktion mit der Webanwendung benötigt werden. Es ist auch wichtig, ein klares Verständnis des Authentifizierungsprozesses und der verschiedenen damit verbundenen Schritte sowie der Daten zu haben, die für die Durchführung der Tests benötigt werden.
Für diesen Blog werden wir eine Anwendung verwenden, die das OIDC-Protokoll für die Authentifizierung beim Identitätsanbieter in der Connext-Plattform nutzt. In der offiziellen Dokumentation von WSO2 erfahren Sie, wie einfach Sie die OIDC-basierte Authentifizierung für Ihre Anwendung aktivieren können. Mit der Yenlo Connext Platform müssen Sie sich nicht um die Feinheiten der Konfigurationen kümmern, denn es handelt sich um einen gemanagten Cloud-Service, der den Großteil der Arbeit für Sie erledigen wird. Ich werde den OIDC-Ablauf hier nicht erklären, da der Schwerpunkt in diesem Blog eher auf dem Testen des Authentifizierungsprozesses liegt.
Ich werde ein Maven-Projekt erstellen, um unsere Testsuite zu schreiben. Nachfolgend finden Sie ein Beispiel für eine Maven POM-Datei mit den erforderlichen Abhängigkeiten und Plugins.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>ConnextSeleniumTest</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>jar</packaging>
<name>ConnextSeleniumTest</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<suiteXmlFile>src/test/resources/testng.xml</suiteXmlFile>
</properties>
<dependencies>
<dependency>
<groupId>org.seleniumhq.selenium</groupId>
<artifactId>selenium-java</artifactId>
<version>4.7.2</version>
</dependency>
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>6.9.10</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-surefire-plugin</artifactId>
<version>2.17</version>
<configuration>
<suiteXmlFiles>
<suiteXmlFile>${suiteXmlFile}</suiteXmlFile>
</suiteXmlFiles>
</configuration>
</plugin>
</plugins>
</build>
</project>
Erforderliche Abhängigkeiten und Plugins für automatisierte Web-Tests mit Selenium und TestNG
Hauptabhängigkeiten:
- Selenium-Java: Hierbei handelt es sich um eine Java-Sprachbindung für den Selenium WebDriver, ein beliebtes Open-Source-Tool zur Automatisierung von Webbrowsern. Die Komponente Selenium-Java bietet eine bequeme Möglichkeit, von einem Java-Programm aus mit Webbrowsern zu interagieren. Damit können Entwickler auf einfache Weise automatisierte Tests schreiben, Daten auslesen oder andere automatisierte Aufgaben im Web durchführen.
- TestNG: Dies ist ein Test-Framework, das bei der Entwicklung von Java-Anwendungen eingesetzt wird. Es stellt ein umfassendes Test-Framework zur Verfügung, das das Schreiben, Verwalten und Ausführen von Tests für Java-Anwendungen erleichtert und so die Qualität der Software und die Effizienz des Testprozesses verbessert.
Plugins:
- Maven Surefire Plugin: Es ist ein Plugin in Apache Maven, das für die Ausführung von Tests und die Erstellung von Berichten verwendet wird. Dieses Plugin wird in der Regel eingesetzt, um in Java geschriebene Tests mit den Test-Frameworks Junit oder TestNG auszuführen. Das Maven Surefire Plugin liefert Berichte in verschiedenen Formaten, beispielsweise als Nur-Text, XML und HTML. Die Berichte stellen Informationen zu den Testergebnissen bereit, z. B. die Anzahl der ausgeführten, bestandenen und fehlgeschlagenen Tests sowie die Details der Testfälle. Die Berichte helfen auch dabei, zu erkennen, welche Tests fehlgeschlagen sind, und sie liefern Informationen, die zum Debuggen und zur Fehlerbehebung der Tests verwendet werden können.
Wenn die Testumgebung eingerichtet ist, besteht der nächste Schritt darin, Testfälle zu schreiben, die verschiedene Szenarien und Benutzerinteraktionen mit der Webanwendung simulieren. Dazu kann die Erstellung von Testfällen gehören, mit denen überprüft wird, ob Benutzer sich erfolgreich anmelden und auf ihr Konto zugreifen können. Außerdem können Testfälle erstellt werden, mit denen überprüft wird, dass die Benutzer nicht auf ihr Konto zugreifen können, wenn sie falsche Anmeldedaten verwenden.
Die folgende Abbildung zeigt die Basispaketstruktur, die ich verwendet habe.
Einrichten der Testumgebung in Selenium mit den @BeforeMethod- und @AfterMethod-Annotationen von TestNG
Bevor wir Testfälle schreiben, müssen wir eine Methode zur Einrichtung der Testumgebung implementieren. TestNG bietet die Annotation @BeforeMethod, um bestimmte Methoden vor jeder Testmethode in einer Testklasse auszuführen. Sehen Sie sich das folgende Beispiel an:
@BeforeMethod
public void setUp() {
ChromeOptions chromeOptions = new ChromeOptions();
//To run in headless mode
chromeOptions.addArguments(Constants.HEADLESS_MODE);
driver = new ChromeDriver(chromeOptions);
js = (JavascriptExecutor) driver;
driver.get(Constants.URL);
System.out.println("Visiting the CCP portal and redirected to login page");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(Constants.IMPLICIT_WAIT, Constants.TIME_UNIT);
}
Bei dieser Methode können wir den Selenium-Webtreiber initialisieren. Da ich meine Tests mit dem Chrome-Browser durchführen werde, habe ich ihn mit dem Chrome-Treiber initialisiert. Es kann jeder beliebige Treiber verwendet werden, den Sie testen möchten.
Ich habe den Headless-Modus für die Ausführung der Tests verwendet, da er schneller und effizienter ist und nicht bei jeder Testausführung einen Browser öffnet. Diese Funktion ist nützlich, wenn Sie Ihre Tests auf einem Server durchführen, der nur den Headless-Modus unterstützt. Um den Headless-Modus zu aktivieren, können Sie ChromeOptions verwenden und ihn dort einstellen.
Die Methode driver.get() in Selenium wird verwendet, um eine Webseite im Browser zu öffnen. Sie benötigt eine URL als Argument und navigiert den Browser zu dieser URL. Bei dieser Methode wird gewartet, bis die Seite vollständig geladen ist und dann wird die Kontrolle an das Testskript zurückgegeben. Wenn die Seite geladen ist, kann das Testskript verschiedene Aktionen auf der Seite ausführen, z. B. auf Schaltflächen klicken, Formulare ausfüllen usw. Die URL, die ich hier verwendet habe, ist die URL des Authentifizierungsendpunkts der Yenlo Connext Platform.
Example: https://<hostname-connext-idp>/oauth2/authorize?response_type=code&client_id=<client-id-of-the-application>&redirect_uri=<URL-of-the-application>
Wenn das Laden von Elementen Ihrer Seite variiert, ist es ratsam, die Methode driver.manage().timeouts().implicitlyWait() einzustellen. Man kann festlegen, wie lange der Treiber warten soll, bis ein Element auf der Seite erscheint, bevor ein Fehler gemeldet wird. Dies gilt für alle Elemente im Gültigkeitsbereich der WebDriver-Instanz. Wenn der Treiber das gewünschte Element also nicht sofort findet, sucht er während des angegebenen Zeitintervalls weiter danach. Da einige Elemente in meiner Anwendung Zeit zum Laden benötigen, habe ich die implizite Wartezeit auf 30 Sekunden festgelegt.
Analog dazu benötigen wir auch eine Methode, die nach jedem Testfall ausgeführt wird, um die Testdaten, die Testumgebung oder andere übliche Testbereinigungsaufgaben zu bereinigen.
Beispiel:
@AfterMethod
public void tearDown() {
driver.quit();
}
Beispieltestfälle zur Überprüfung erfolgreicher und nicht erfolgreicher Benutzeranmeldung in der Yenlo Connext Plattform
Jetzt können wir mit dem Schreiben der Testfälle beginnen. Nachfolgend finden Sie zwei Beispieltestfälle zum Testen. Der erste simuliert eine erfolgreiche Benutzeranmeldung und überprüft, ob Benutzer sich erfolgreich anmelden können. Der zweite Testfall simuliert eine fehlgeschlagene Anmeldung und überprüft, dass Benutzer nicht auf ihr Konto zugreifen können, wenn sie falsche Anmeldedaten angeben.
@Test (priority = 1)
public void testCCPLogin() {
//Create login page factory object.
ccpLoginPage = new CCPLoginPage(driver);
assertPageTitle();
ccpLoginPage.loginToCCP(Constants.USER_NAME, Constants.PASSWORD);
landingToApplication();
}
@Test (priority = 2)
private void testIncorrectUsername(){
ccpLoginPage = new CCPLoginPage(driver);
assertPageTitle();
ccpLoginPage.loginToCCP(Constants.INCORRECT_USER_NAME,Constants.PASSWORD);
redirectingToErrorMessage();
}
Um eine Methode als Testfall zu markieren, müssen Sie die Annotation @Test in TestNG verwenden. Um dann die Reihenfolge der Testausführung anzugeben, können Sie das Prioritätsattribut „priority“ verwenden. Die niedrigste Nummer wird zuerst ausgeführt.
Beispieltestfälle zum Testen von Sicherheitsfunktionen und UI-Funktionalität von Anmeldeseiten
Neben diesen Basistestfällen ist es auch wichtig, die verschiedenen Sicherheitsfunktionen zu testen, die typischerweise in Webanwendungen verwendet werden, um Benutzerdaten zu schützen und unbefugten Zugriff zu verhindern. So können Sie z. B. testen, ob die Benutzer nach einer bestimmten Zeitspanne aufgefordert werden, ihr Passwort zu ändern, oder ob das Passwortfeld maskiert ist. Sie können auch das SSO-Verhalten Ihrer Anwendungen testen.
Neben den Anmeldevorgängen können Sie auch testen, ob die grundlegenden UI-Funktionen für Ihre Anmeldeseiten ordnungsgemäß funktionieren oder ob die erforderlichen Logobilder vorhanden sind.
Im Folgenden finden Sie ein Beispiel für einen Testfall, der überprüft, ob die Bilder auf der Anmeldeseite fehlerhaft sind.
@Test(priority = 3)
private void testBrokenImages(){
ccpLoginPage = new CCPLoginPage(driver);
int brokenImagesCount = 0;
List<WebElement> imageList = ccpLoginPage.images;
System.out.println("The page under test has " + imageList.size() + " images.");
for (WebElement image : imageList) {
if (image != null) {
String imagePath = image.getAttribute("src");
if (!isImageAvailable(imagePath)) {
brokenImagesCount++;
System.out.println(image.getAttribute("outerHTML") + " is broken.");
} else {
System.out.println("Image at " + image.getAttribute("outerHTML") + " is available");
}
}
}
System.out.println("The Connext Login page"+ " has " + brokenImagesCount + " broken images");
}
private boolean isImageAvailable(String imagePath) {
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(imagePath);
try {
HttpResponse response = client.execute(request);
int responseCode = response.getStatusLine().getStatusCode();
/* For valid images, the HttpStatus will be 200 */
if (responseCode != 200) {
return false;
} else {
return true;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
Um zu prüfen, ob die Bilder vorhanden sind, müssen wir einen HTTP-GET-Aufruf zum Bildpfad durchführen. Daher müssen wir unserem Maven-Projekt die Abhängigkeit ‚httpclient‘ hinzufügen.
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.13</version>
</dependency>
Beispieltestfälle für Verschlüsselung und SSO-Funktionen
Im Folgenden finden Sie ein Beispiel für einen Testfall, der überprüft, ob das Passwortfeld maskiert ist.
@Test(priority = 4)
public void testPasswordEncryption() {
ccpLoginPage = new CCPLoginPage(driver);
WebElement passwordElement = ccpLoginPage.getPasswordElement();
boolean isEncrypted = passwordElement.getAttribute("type").equals("password");
Assert.assertEquals(isEncrypted, true, "Password field is not masked.");
}
Im Folgenden finden Sie ein Beispiel für einen Testfall, der die SSO-Funktion testet.
@Test(priority = 5)
public void testSSO() throws AWTException {
ccpLoginPage = new CCPLoginPage(driver);
assertPageTitle();
ccpLoginPage.loginToCCP(Constants.USER_NAME, Constants.PASSWORD);
landingToApplication();
//Use a url of an application that is SSOed with the CCP portal
switchToNewTab("https://test-portal.com/ssoapplication/dashboard");
}
private void switchToNewTab(String url) {
String currentHandle = driver.getWindowHandle();
((JavascriptExecutor) driver).executeScript("window.open()");
Set<String> handles = driver.getWindowHandles();
for (String handle : handles) {
if (!handle.equalsIgnoreCase(currentHandle)) {
driver.switchTo().window(handle);
driver.get(url);
landingToSSOApplication();
}
}
}
private void landingToApplication(){
ccpHomePage = new CCPHomePage(driver);
ccpHomePage.waitUntilHomePageLoads();
String applicationTitle = driver.getTitle();
String expectedApplicationTitle = "Connext Customer Care Portal - Dashboard";
Assert.assertEquals(applicationTitle,expectedApplicationTitle,"Application page title doesn't match");
String expectedApplicationUrl="https://test-portal.com/application/dashboard";
String applicationUrl= driver.getCurrentUrl();
Assert.assertEquals(applicationUrl,expectedApplicationUrl,"Application url after login is not a match.");
}
private void landingToSSOApplication(){
ccpHomePage = new CCPHomePage(driver);
ccpHomePage.waitUntilHomePageLoads();
String applicationTitle = driver.getTitle();
String expectedApplicationTitle = "Connext Customer Care Portal - Dashboard";
Assert.assertEquals(applicationTitle,expectedApplicationTitle,"Application page title doesn't match");
String expectedApplicationUrl="https://test-portal.com/ssoapplication/dashboard";
String applicationUrl= driver.getCurrentUrl();
Assert.assertEquals(applicationUrl,expectedApplicationUrl,"Application url after login is not a match.");
}
Die Methode ’switchToNewTab‘ sorgt dafür, dass innerhalb derselben Browsersitzung eine andere Registerkarte geöffnet und eine andere Anwendung geladen wird, deren Authentifizierung mit der früheren Anwendung über SSO erfolgt.
Die Methode „landingToApplication“ überprüft, ob der Benutzer in der Anwendung angemeldet ist.
Die Methode „landingToSSOApplication“ überprüft, ob der Benutzer in der anderen SSO-Anwendung angemeldet ist.
Hören Sie hier nicht auf! Am Ende dieses Blogs erwartet Sie ein Bonus zur Selenium-Testfälle-Klasse.
Möchten Sie Ihr Identitäts- Und Zugangsmanagement Gleich Von Anfang An Richtig Regeln?
Jetzt herunterladenPOM und Page Factory-Klasse zum Testen des Authentifizierungsprozesses verwenden
Eine der Herausforderungen beim Testen des Authentifizierungsprozesses liegt darin, dass oft eine Interaktion mit mehreren Seiten, Elementen und Formularen innerhalb der Webanwendung erforderlich ist. Um diesen Prozess einfacher und effizienter zu gestalten, verwenden viele Tester das Page Object Model (POM) Design Pattern in Verbindung mit der Page Factory-Klasse, die in das Selenium-Framework integriert ist. Dank des POM-Patterns können Tester die Details der Interaktion mit den verschiedenen Elementen einer Seite in wiederverwendbaren Objekten zusammenfassen. Auf diese Objekte kann dann in verschiedenen Testfällen problemlos verwiesen werden.
Die Page Factory-Klasse ist ein leistungsstarkes Tool für die Implementierung des POM-Patterns. Damit können Tester die Elemente einer Seite mittels Annotationen definieren, auf die sie dann in ihren Testfällen einfach verweisen können. Beispielsweise könnte eine Anmeldeseite ein Textfeld für den Benutzernamen, ein Textfeld für das Passwort und eine Schaltfläche zum Senden enthalten. Die Page Factory-Klasse macht es einfach, diese Elemente in einer einzigen Klasse zu definieren und dann in verschiedenen Testfällen auf sie zu verweisen.
Wenn Sie unsere Testfälle durchgehen, finden Sie Verweise auf Klassen mit der Bezeichnung „CCPLoginPage“ und „CCPHomePage“.
Beispiel:
@Test(priority = 1)
public void testCCPLogin() {
//Create login page factory object.
ccpLoginPage = new CCPLoginPage(driver);
assertPageTitle();
ccpLoginPage.loginToCCP(Constants.USER_NAME, Constants.PASSWORD);
landingToApplication();
}
Diese beiden Klassen sind die „Page Factory-Klassen“ und stellen die Anmeldeseite bzw. die Startseite der Anwendung dar.
Sie können die @FindBy-Annotation in einem Klassenattribut verwenden und in Selenium in eine Page Factory-Klasse umwandeln.
Im Beispiel sehen Sie die Felder für den Benutzernamen, das Passwort und die Anmeldeschaltfläche in der CCPLoginPage Page Factory-Klasse.
public class CCPLoginPage {
private WebDriver driver;
@FindBy(id="username")
WebElement usernameElement;
@FindBy(id="password")
WebElement passwordElement;
@FindBy(css=".wr-btn")
WebElement loginButtonElement;
public CCPLoginPage (WebDriver webDriver){
this.driver = webDriver;
PageFactory.initElements(driver, this);
}
Die oben aufgeführte Klasse bildet die folgenden UI-Elemente auf der Anmeldeseite ab.
<inputid=“username“ name=“username“ type=“text“ class=“form-control“ tabindex=“0″ placeholder=“Username“ required autofocus>
<inputid=“password“ name=“password“ type=“password“ class=“form-control“ placeholder=“Password“ autocomplete=“off“>
<button class=“wr-btn grey-bg col-xs-12 col-md-12 col-lg-12 margin-bottom-double“ type=“submit“> Login </button>
Damit diese Klasse als Page Factory-Objekt fungieren kann, müssen Sie PageFactory.initElements() im Konstruktor aufrufen.
Dann können Sie innerhalb dieser Klasse Methoden schreiben, die die Werte für diese Elemente festlegen, und dann die Informationen übermitteln. Die vollständigen Quellen für CCPLoginPage und CCPHomePage finden Sie im Bonusbereich am Ende dieses Blogs.
Assertions in Selenium-Testfällen
Assertions werden verwendet, um das erwartete Verhalten einer Softwareanwendung während des Testens zu validieren. Sie sind ein wichtiger Bestandteil des automatisierten Testens und sorgen dafür, dass die Anwendung korrekt funktioniert. Eine Assertion prüft eine bestimmte Bedingung. Wenn die Bedingung nicht erfüllt ist, schlägt die Assertion fehl, löst eine Ausnahme aus und markiert den Testfall als fehlgeschlagen. Einige häufig verwendete Assertions in Selenium und anderen Test-Frameworks sind:
- assertEquals: Diese Assertion prüft, ob zwei Werte gleich sind, und löst eine Ausnahme aus, wenn sie es nicht sind.
- assertTrue: Diese Assertion prüft, ob eine Bedingung wahr ist, und löst eine Ausnahme aus, wenn sie falsch ist.
- assertFalse: Diese Assertion prüft, ob eine Bedingung falsch ist, und löst eine Ausnahme aus, wenn sie wahr ist.
- assertNull: Diese Assertion prüft, ob ein Wertnull ist, und löst eine Ausnahme aus, wenn sie es nicht ist.
- assertNotNull: Diese Assertion prüft, ob ein Wert nicht null ist, und löst eine Ausnahme aus, wenn sie es ist.
Diese Assertions werden in Verbindung mit Test-Frameworks wie TestNG, JUnit usw. verwendet, um das Verhalten der zu testenden Softwareanwendung zu validieren.
In unseren Testfällen haben wir die folgenden Assertions gemacht:
Anmeldung bei der Anwendung:
- Titel der Anmeldeseite prüfen
- Titel der Anwendungsseite nach der Anmeldung bei der Anwendung prüfen
- Anwendungs-URL nach der Anmeldung bei der Anwendung prüfen
Falscher Nutzername:
- Titel der Anmeldeseite prüfen
- Meldung über fehlgeschlagene Anmeldung prüfen
Passwortmaskierung:
- Prüfen, ob das Passwortfeld maskiert ist oder nicht
SSO:
- Anwendungs-URL und den Titel vor SSO prüfen
- Anwendungs-URL und den Titel der anderen SSO-Anwendung nach SSO prüfen
TestNG-Framework für die Testausführung einrichten
Jetzt können Sie Ihre Testklasse im TestNG-Framework registrieren, indem Sie Ihrer testng.xml folgenden Eintrag hinzufügen.
<suite name="Suite1" verbose="1" >
<test name="CCPLogin" >
<classes>
<class name="org.yenlo.sample.CCPLoginSeleniumTest" />
</classes>
</test>
</suite>
Dann können Sie in Ihren Projektstamm gehen und den Befehl „mvn test“ ausführen, um die Tests auszuführen.
Sobald die Testausführung abgeschlossen ist, können Sie den Ordner „target/surefire-reports“ öffnen und verschiedene Berichte der Testausführung einsehen.
Fazit: Testen des Authentifizierungsprozesses einer Webanwendung
Letztendlich ist es wichtig, den Authentifizierungsprozess als Teil des Entwicklungsprozesses kontinuierlich zu testen. Dazu können regelmäßige automatisierte Tests sowie manuelle Tests durchgeführt werden, um sicherzustellen, dass der Authentifizierungsprozess weiterhin korrekt funktioniert, wenn Änderungen an der Webanwendung vorgenommen werden.
Zusammenfassend lässt sich sagen, dass das Testen des Authentifizierungsprozesses einer Webanwendung eine wichtige und komplexe Aufgabe ist, die ein tiefes Verständnis der verschiedenen involvierten Technologien und Protokolle sowie ein klares Verständnis des Authentifizierungsprozesses selbst erfordert. Durch die Verwendung von Selenium in Verbindung mit Page Object Model und Page Factory können Tester problemlos Testfälle schreiben und ausführen, die echte Benutzerinteraktionen mit der Webanwendung simulieren und überprüfen, ob der Authentifizierungsprozess ordnungsgemäß funktioniert. Durch kontinuierliches Testen als Teil des Entwicklungsprozesses können Entwickler sicherstellen, dass der Authentifizierungsprozess sicher und funktionsfähig bleibt, wenn sich die Webanwendung im Laufe der Zeit weiterentwickelt.
BONUS: Beispiel für Selenium-Testfälle-Klasse für Webanwendungen
- Selenium-Testfälle-Klasse.
package org.yenlo.sample;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.HttpClientBuilder;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import org.testng.Assert;
import org.testng.annotations.*;
import org.yenlo.sample.pagefactory.CCPHomePage;
import org.yenlo.sample.pagefactory.CCPLoginPage;
import org.yenlo.sample.pagefactory.util.Constants;
import java.awt.*;
import java.io.IOException;
import java.time.Duration;
import java.util.List;
import java.util.Set;
public class CCPLoginSeleniumTest {
private WebDriver driver;
JavascriptExecutor js;
//Login page element repository
CCPLoginPage ccpLoginPage;
CCPHomePage ccpHomePage;
@BeforeMethod
public void setUp() {
ChromeOptions chromeOptions = new ChromeOptions();
//To run in headless mode
chromeOptions.addArguments(Constants.HEADLESS_MODE);
driver = new ChromeDriver(chromeOptions);
js = (JavascriptExecutor) driver;
driver.get(Constants.URL);
System.out.println("Visiting the CCP portal and redirected to login page");
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(Constants.IMPLICIT_WAIT, Constants.TIME_UNIT);
}
@AfterMethod
public void tearDown() {
driver.quit();
}
@Test(priority = 1)
public void testCCPLogin() {
//Create login page factory object.
ccpLoginPage = new CCPLoginPage(driver);
assertPageTitle();
ccpLoginPage.loginToCCP(Constants.USER_NAME, Constants.PASSWORD);
landingToApplication();
}
@Test(priority = 2)
private void testIncorrectUsername(){
ccpLoginPage = new CCPLoginPage(driver);
assertPageTitle();
ccpLoginPage.loginToCCP(Constants.INCORRECT_USER_NAME, Constants.PASSWORD);
redirectingToErrorMessage();
}
@Test(priority = 3)
private void testBrokenImages(){
ccpLoginPage = new CCPLoginPage(driver);
int brokenImagesCount = 0;
List<WebElement> imageList = ccpLoginPage.images;
System.out.println("The page under test has " + imageList.size() + " images.");
for (WebElement image : imageList) {
if (image != null) {
String imagePath = image.getAttribute("src");
if (!isImageAvailable(imagePath)) {
brokenImagesCount++;
System.out.println(image.getAttribute("outerHTML") + " is broken.");
} else {
System.out.println("Image at " + image.getAttribute("outerHTML") + " is available");
}
}
}
System.out.println("The Connext Login page"+ " has " + brokenImagesCount + " broken images");
}
@Test(priority = 4)
public void testPasswordEncryption() {
ccpLoginPage = new CCPLoginPage(driver);
WebElement passwordElement = ccpLoginPage.getPasswordElement();
boolean isEncrypted = passwordElement.getAttribute("type").equals("password");
Assert.assertEquals(isEncrypted, true, "Password field is not masked.");
}
@Test(priority = 5)
public void testSSO() throws AWTException {
ccpLoginPage = new CCPLoginPage(driver);
assertPageTitle();
ccpLoginPage.loginToCCP(Constants.USER_NAME, Constants.PASSWORD);
landingToApplication();
//Use a url of an application that is SSOed with the CCP portal
switchToNewTab(" https://test-portal.com/ssoapplication/dashboard ");
}
private void switchToNewTab(String url) {
String currentHandle = driver.getWindowHandle();
((JavascriptExecutor) driver).executeScript("window.open()");
Set<String> handles = driver.getWindowHandles();
for (String handle : handles) {
if (!handle.equalsIgnoreCase(currentHandle)) {
driver.switchTo().window(handle);
driver.get(url);
landingToSSOApplication();
}
}
}
/**
* Verify login page title.
*/
private void assertPageTitle() {
String loginPageTitle = driver.getTitle();
String expectedLoginPageTitle = "Connext Identity Server";
Assert.assertEquals(loginPageTitle, expectedLoginPageTitle, "Connext login page title doesn't match");
}
private void landingToApplication(){
ccpHomePage = new CCPHomePage(driver);
ccpHomePage.waitUntilHomePageLoads();
String applicationTitle = driver.getTitle();
String expectedApplicationTitle = "Connext Customer Care Portal - Dashboard";
Assert.assertEquals(applicationTitle,expectedApplicationTitle,"Application page title doesn't match");
String expectedApplicationUrl="https://test-portal.com/application/dashboard";
String applicationUrl= driver.getCurrentUrl();
Assert.assertEquals(applicationUrl,expectedApplicationUrl,"Application url after login is not a match.");
}
/**
* Method to load the application that is in SSO with the CCP portal.
* Here I have used the same CCP portal. But you can update the method to use a different application URL.
*/
private void landingToSSOApplication(){
ccpHomePage = new CCPHomePage(driver);
ccpHomePage.waitUntilHomePageLoads();
String applicationTitle = driver.getTitle();
String expectedApplicationTitle = "Connext Customer Care Portal - Dashboard";
Assert.assertEquals(applicationTitle,expectedApplicationTitle,"Application page title doesn't match");
String expectedApplicationUrl=" https://test-portal.com/ssoapplication/dashboard ";
String applicationUrl= driver.getCurrentUrl();
Assert.assertEquals(applicationUrl,expectedApplicationUrl,"Application url after login is not a match.");
}
private void redirectingToErrorMessage(){
ccpLoginPage.waitUntilErrorMessageLoads();
assertFailedLoginMessage();
}
private void assertFailedLoginMessage(){
String errorNotification = ccpLoginPage.getFailedLoginMessage();
String expectedErrorNotification = "Login failed! Please recheck the username and password and try again.";
Assert.assertEquals(errorNotification,expectedErrorNotification,"Expected error message is not matching");
}
private boolean isImageAvailable(String imagePath) {
HttpClient client = HttpClientBuilder.create().build();
HttpGet request = new HttpGet(imagePath);
try {
HttpResponse response = client.execute(request);
int responseCode = response.getStatusLine().getStatusCode();
/* For valid images, the HttpStatus will be 200 */
if (responseCode != 200) {
return false;
} else {
return true;
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
2. CCPLoginPage- und CCPHomePage Page Factory-Klassen.
package org.yenlo.sample.pagefactory;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
import java.util.List;
public class CCPLoginPage {
private WebDriver driver;
@FindBy(id="username")
WebElement usernameElement;
@FindBy(id="password")
WebElement passwordElement;
@FindBy(css=".wr-btn")
WebElement loginButtonElement;
@FindBy(className = "alert-danger")
WebElement failedLoginNotificationElement;
@FindBy(tagName = "img")
public List<WebElement> images;
String failedLoginNotificationClassName = "alert-danger";
public CCPLoginPage(WebDriver webDriver){
this.driver = webDriver;
PageFactory.initElements(driver, this);
}
//Set username in username text box
public void setUsername(String username){
usernameElement.clear();
usernameElement.sendKeys(username);
System.out.println("Entering the username");
}
//Set password in password text box
public void setPassword(String password){
passwordElement.clear();
passwordElement.sendKeys(password);
System.out.println("entering the password");
}
//Submit username & password
public void clickLogin(){
loginButtonElement.click();
System.out.println("Clicking login button");
}
/**
* Method to call from the testcase, to login a user
*/
public void loginToCCP(String username, String password){
//fill username
this.setUsername(username);
//fill password
this.setPassword(password);
//click login button
this.clickLogin();
}
public void waitUntilErrorMessageLoads(){
WebDriverWait wdw = new WebDriverWait(driver, Duration.ofSeconds(30)); // wait up to 30 seconds
wdw.until(ExpectedConditions.visibilityOfElementLocated(By.className(failedLoginNotificationClassName)));
}
public String getFailedLoginMessage(){
return failedLoginNotificationElement.getText();
}
public WebElement getPasswordElement(){
return passwordElement;
}
}
package org.yenlo.sample.pagefactory;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.PageFactory;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;
import java.time.Duration;
/**
* CCP home page web element repository
*/
public class CCPHomePage {
private WebDriver driver;
String ccpHomePageElementXpath = "//span[text()='Dashboard']";
public CCPHomePage(WebDriver webDriver){
this.driver = webDriver;
PageFactory.initElements(driver, this);
}
/**
* Method to wait until CCP home page loads after login.
*/
public void waitUntilHomePageLoads(){
WebDriverWait wdw = new WebDriverWait(driver, Duration.ofSeconds(30)); // wait up to 30 seconds
wdw.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(ccpHomePageElementXpath)));
}
}