selenium-webdriver
Seitenobjektmodell
Suche…
Einführung
By
Klasse gefunden. Diese Locators und Interaktionen werden als bewährte Methode in Page Objects eingefügt, um doppelten Code zu vermeiden und die Wartung zu vereinfachen. Es kapselt WebElements
und nimmt an, Verhalten und WebElements
auf der Seite (oder einem Teil einer Seite in einer Web-App) zu enthalten.
Bemerkungen
Das Seitenobjektmodell ist ein Muster, in dem wir objektorientierte Klassen schreiben, die als Schnittstelle zu einer bestimmten Ansicht einer Webseite dienen. Wir verwenden die Methoden dieser Seitenklasse, um die erforderliche Aktion auszuführen. Vor einigen Jahren manipulierten wir den HTML-Code der Webseite direkt in Testklassen, was sehr schwierig zu pflegen war und zusammen mit den Änderungen der Benutzeroberfläche sehr spröde war.
Wenn Sie Ihren Code jedoch so organisieren, dass das Seitenobjektmuster so angeordnet ist, steht Ihnen eine anwendungsspezifische API zur Verfügung, mit der Sie die Seitenelemente bearbeiten können, ohne sich im HTML-Bereich zu bewegen. Die grundlegende Daumenlehne besagt, dass Ihr Seitenobjekt alles enthalten sollte, was ein Mensch auf dieser Webseite tun kann. Um beispielsweise auf das Textfeld auf einer Webseite zuzugreifen, sollten Sie dort eine Methode verwenden, um den Text abzurufen und nach allen Änderungen den String zurückzugeben.
Einige wichtige Punkte, die Sie beim Entwerfen der Seitenobjekte beachten sollten:
Das Seitenobjekt sollte in der Regel nicht nur für Seiten erstellt werden, Sie sollten es jedoch lieber für bedeutende Elemente der Seite erstellen. Beispielsweise sollte eine Seite mit mehreren Registerkarten zum Anzeigen verschiedener Diagramme Ihrer Wissenschaftler die gleiche Anzahl von Seiten haben wie die Anzahl der Registerkarten.
Wenn Sie von einer Ansicht zur anderen navigieren, sollte die Instanz der Seitenklassen zurückgegeben werden.
Die Dienstprogrammmethoden, die nur für eine bestimmte Ansicht oder Webseite vorhanden sein müssen, sollten nur zu dieser Seitenklasse gehören.
Die Assertion-Methoden sollten nicht von Seitenklassen beachtet werden. Sie können Methoden haben, um boolean zurückzugeben, aber sie dort nicht zu überprüfen. Um beispielsweise den vollständigen Namen des Benutzers zu überprüfen, können Sie eine Methode zum Abrufen eines booleschen Werts verwenden:
public boolean hasDisplayedUserFullName (String userFullName) { return driver.findElement(By.xpath("xpathExpressionUsingFullName")).isDisplayed(); }
Wenn Ihre Webseite auf iframe basiert, sollten Sie auch Seitenklassen für iframes verwenden.
Vorteile des Page Object Pattern:
- Saubere Trennung zwischen Testcode und Seitencode
- Im Falle einer Änderung der Benutzeroberfläche der Webseite müssen Sie Ihren Code nicht an mehreren Stellen ändern. Ändern Sie nur in Seitenklassen.
- Keine Streuelemente.
- Macht den Code verständlicher
- Einfache Wartung
Einführung (mit Java)
Ein Beispiel für den Anmeldetest basierend auf dem Seitenobjektmuster:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
/**
* Class which models the view of Sign-In page
*/
public class SignInPage {
@FindBy(id="username")
private usernameInput;
@FindBy(id="password")
private passwordInput;
@FindBy(id="signin")
private signInButton;
private WebDriver driver;
public SignInPage(WebDriver driver) {
this.driver = driver;
}
/**
* Method to perform login
*/
public HomePage performLogin(String username, String password) {
usernameInput.sendKeys(username);
passwordInput.sendKeys(password);
signInButton.click();
return PageFactory.initElements(driver, HomePage.class);
}
}
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
/**
* Class which models the view of home page
*/
public class HomePage {
@FindBy(id="logout")
private logoutLink;
private WebDriver driver;
public HomePage(WebDriver driver) {
this.driver = driver;
}
/**
* Method to log out
*/
public SignInPage logout() {
logoutLink.click();
wait.ForPageToLoad();
return PageFactory.initElements(driver, SignInPage.class);
}
}
/**
* Login test class
*/
public class LoginTest {
public void testLogin() {
SignInPage signInPage = new SignInPage(driver);
HomePage homePage = signInPage.login(username, password);
signInPage = homePage.logout();
}
}
C #
Seitenobjekte sollten Verhalten enthalten, Informationen zu Zusicherungen zurückgeben und möglicherweise eine Methode für die Seitenbereitschaftsmethode bei der Initialisierung. Selen unterstützt Seitenobjekte mit Annotationen. In C # ist es wie folgt:
using OpenQA.Selenium;
using OpenQA.Selenium.Support.PageObjects;
using OpenQA.Selenium.Support.UI;
using System;
using System.Collections.Generic;
public class WikipediaHomePage
{
private IWebDriver driver;
private int timeout = 10;
private By pageLoadedElement = By.ClassName("central-featured-logo");
[FindsBy(How = How.Id, Using = "searchInput")]
[CacheLookup]
private IWebElement searchInput;
[FindsBy(How = How.CssSelector, Using = ".pure-button.pure-button-primary-progressive")]
[CacheLookup]
private IWebElement searchButton;
public ResultsPage Search(string query)
{
searchInput.SendKeys(query);
searchButton.Click();
}
public WikipediaHomePage VerifyPageLoaded()
{
new WebDriverWait(driver, TimeSpan.FromSeconds(timeout)).Until<bool>((drv) => return drv.ExpectedConditions.ElementExists(pageLoadedElement));
return this;
}
}
Anmerkungen:
-
CacheLookup
speichert das Element im Cache und speichert bei jedem Aufruf ein neues Element zurück. Dies verbessert die Leistung, eignet sich jedoch nicht für dynamisch wechselnde Elemente. -
searchButton
hat 2 Klassennamen und keine ID. Aus diesem Grund kann ich weder Klassennamen noch IDs verwenden. - Ich habe bestätigt, dass meine Locators das von mir gewünschte Element mit den Developer Tools (für Chrome) zurückgeben. In anderen Browsern können Sie FireBug oder ähnliches verwenden.
-
Search()
Methode gibt ein anderesResultsPage
(ResultsPage
) zurück, wenn Sie mit dem Suchklick auf eine andere Seite umleiten.
Best Practices-Seite Objektmodell
- Erstellen Sie separate Dateien für Kopf- und Fußzeilen (da sie für alle Seiten üblich sind und es nicht sinnvoll ist, sie zu einem Teil einer Seite zu machen)
- Gemeinsame Elemente (wie Suchen / Zurück / Weiter usw.) in separaten Dateien aufbewahren (Du sollst jegliche Art von Duplizierungen entfernen und die Trennung logisch halten)
- Für Driver ist es eine gute Idee, eine separate Driver-Klasse zu erstellen und Driver als statisch zu halten, damit auf alle Seiten zugegriffen werden kann! (Ich habe alle meine Webseiten DriverClass erweitern)
- Die in PageObjects verwendeten Funktionen sind in kleinstmögliche Blöcke unterteilt, wobei die Häufigkeit und die Art und Weise, in der sie aufgerufen werden, berücksichtigt wird (die Art und Weise, wie sie für die Anmeldung verwendet werden. Die Anmeldung kann zwar in die Funktionen enterUsername und enterPassword unterteilt werden, sie behält sie jedoch bei da die Login-Funktion logischer ist, da in den meisten Fällen die Login-Funktion aufgerufen wird, anstatt separate Aufrufe von enterUsername und enterPassword-Funktionen durchzuführen.
- Die Verwendung von PageObjects selbst trennt das Testskript von den elementLocators
- Nützliche Funktionen in separaten utils-Ordnern (wie DateUtil, ExcelUtils usw.)
- Konfigurationen in separaten conf-Ordnern haben (z. B. Festlegen der Umgebung, in der die Tests ausgeführt werden sollen, Konfigurieren der Ausgabe- und Eingabeordner)
- Bei Fehlschlagen screenCapture einbinden
- Haben Sie eine statische Wartevariable in der DriverClass mit einer impliziten Wartezeit wie Sie getan haben. Versuchen Sie immer, bedingte Wartezeiten zu haben, anstatt statische Wartezeiten wie: wait.until (ExpectedConditions). Dadurch wird sichergestellt, dass das Warten die Ausführung nicht unnötig verlangsamt.