Model stránky a továrna v Selenium
Co je objektový model stránky?
Model objektu stránky (POM) je návrhový vzor, populárně používaný v automatizaci testování, který vytváří Object Repository pro prvky webového uživatelského rozhraní. Výhodou modelu je, že snižuje duplicitu kódu a zlepšuje údržbu testů.
Podle tohoto modelu by pro každou webovou stránku v aplikaci měla existovat odpovídající třída stránky. Tato třída stránky bude identifikovat WebElements dané webové stránky a také obsahuje metody Page, které provádějí operace s těmito WebElements. Název těchto metod by měl být uveden podle úlohy, kterou provádějí, tj. pokud nakladač čeká na zobrazení platební brány, název metody POM může být waitForPaymentScreenDisplay().
Proč objektový model stránky?
Spuštění automatizace uživatelského rozhraní v Selenium WebDriver NENÍ náročný úkol. Musíte jen najít prvky, provádět s nimi operace.
Zvažte tento jednoduchý skript pro přihlášení na web
Jak můžete pozorovat, vše, co děláme, je hledání prvků a plnění hodnot pro tyto prvky.
Toto je malý skript. Údržba skriptů vypadá snadno. Ale s časem testovací sada poroste. Jak do kódu přidáváte další a další řádky, věci se stávají složitějšími.
Hlavním problémem údržby skriptů je, že pokud 10 různých skriptů používá stejný prvek stránky, při jakékoli změně v tomto prvku musíte změnit všech 10 skriptů. To je časově náročné a náchylné k chybám.
Lepší přístup k údržbě skriptů je vytvořit samostatný soubor třídy, který by našel webové prvky, naplnil je nebo je ověřil. Tuto třídu lze znovu použít ve všech skriptech používajících tento prvek. Pokud v budoucnu dojde ke změně webového prvku, musíme provést změnu pouze v 1 souboru třídy a ne v 10 různých skriptech.
Tento přístup se nazývá Page Object Model in Selenium. Pomáhá to, aby byl kód čitelnější, udržovatelnější a znovu použitelný.
Výhody POM
- Vzor návrhu objektu stránky říká, že operace a toky v uživatelském rozhraní by měly být odděleny od ověřování. Díky tomuto konceptu je náš kód čistší a snadno pochopitelný.
- Druhou výhodou je, že úložiště objektů je nezávislé na testovacích případech, takže můžeme použít stejné úložiště objektů pro různé účely s různými nástroji. Můžeme například integrovat objektový model stránky Selenium s TestNG/JUnit pro funkční Testování a zároveň s JBehave/Cucumber pro přejímací zkoušky.
- Kód se stává méně a optimalizuje se díky opakovaně použitelným metodám stránek ve třídách POM.
- Metody získávají realističtější názvy, které lze snadno mapovat podle operace probíhající v uživatelském rozhraní. tj. pokud po kliknutí na tlačítko přistaneme na domovské stránce, název metody bude jako 'gotoHomePage()'.
Jak implementovat POM?
Jednoduchý POM:
Je to základní struktura rámce objektového modelu stránky, kde jsou všechny webové prvky AUT a metody, které fungují na těchto webových prvcích, jsou udržovány uvnitř souboru třídy. Úloha, jako je ověřování, by měla být samostatná jako součást testovacích metod.
Kompletní příklad
modelový případ: Přejděte na ukázkový web Guru99.
Krok 1) Přejděte na ukázkovou stránku Guru99
Krok 2) Na domovské stránce zkontrolujte, zda je přítomen text „Guru99 Bank“.
Krok 3) Přihlaste se do aplikace
Krok 4) Ověřte, že domovská stránka obsahuje text jako „ID správce: demo“
Tady máme co do činění se 2 stránkami
- Přihlásit se Strana
- Domovská stránka (zobrazí se po přihlášení)
Podle toho vytvoříme 2 POM in Selenium třídy
Guru99 Přihlašovací stránka POM
package pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class Guru99Login { WebDriver driver; By user99GuruName = By.name("uid"); By password99Guru = By.name("password"); By titleText =By.className("barone"); By login = By.name("btnLogin"); public Guru99Login(WebDriver driver){ this.driver = driver; } //Set user name in textbox public void setUserName(String strUserName){ driver.findElement(user99GuruName).sendKeys(strUserName); } //Set password in password textbox public void setPassword(String strPassword){ driver.findElement(password99Guru).sendKeys(strPassword); } //Click on login button public void clickLogin(){ driver.findElement(login).click(); } //Get the title of Login Page public String getLoginTitle(){ return driver.findElement(titleText).getText(); } /** * This POM method will be exposed in test case to login in the application * @param strUserName * @param strPasword * @return */ public void loginToGuru99(String strUserName,String strPasword){ //Fill user name this.setUserName(strUserName); //Fill password this.setPassword(strPasword); //Click Login button this.clickLogin(); } }
Domovská stránka Guru99 POM in Selenium
package pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class Guru99HomePage { WebDriver driver; By homePageUserName = By.xpath("//table//tr[@class='heading3']"); public Guru99HomePage(WebDriver driver){ this.driver = driver; } //Get the User name from Home Page public String getHomePageDashboardUserName(){ return driver.findElement(homePageUserName).getText(); } }
Guru99 Jednoduchý POM in Selenium Modelový případ
package test; import java.util.concurrent.TimeUnit; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import pages.Guru99HomePage; import pages.Guru99Login; public class Test99GuruLogin { String driverPath = "C:\\geckodriver.exe"; WebDriver driver; Guru99Login objLogin; Guru99HomePage objHomePage; @BeforeTest public void setup(){ System.setProperty("webdriver.gecko.driver", driverPath); driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://demo.guru99.com/V4/"); } /** * This test case will login in https://demo.guru99.com/V4/ * Verify login page title as guru99 bank * Login to application * Verify the home page using Dashboard message */ @Test(priority=0) public void test_Home_Page_Appear_Correct(){ //Create Login Page object objLogin = new Guru99Login(driver); //Verify login page title String loginPageTitle = objLogin.getLoginTitle(); Assert.assertTrue(loginPageTitle.toLowerCase().contains("guru99 bank")); //login to application objLogin.loginToGuru99("mgr123", "mgr!23"); // go the next page objHomePage = new Guru99HomePage(driver); //Verify home page Assert.assertTrue(objHomePage.getHomePageDashboardUserName().toLowerCase().contains("manger id : mgr123")); }
V čem je Page Factory Selenium?
Page Factory v Selenium je vestavěný koncept rámce Page Object Model pro Selenium WebDriver je ale velmi optimalizovaný. Používá se k inicializaci objektů Page nebo k vytvoření instance samotného objektu Page. Používá se také k inicializaci prvků třídy Page bez použití „FindElement/s“.
I zde se řídíme konceptem oddělení Page Object Repository a testovacích metod. Navíc s pomocí třídy PageFactory v Selenium, používáme anotace @FindBy najít WebElement. K inicializaci webových prvků používáme metodu initElements
@FindBy může přijmout tagName, částečnýLinkText, name, linkText, id, css, className, xpath jako atributy.
Podívejme se na stejný příklad jako výše pomocí Page Factory
Přihlašovací stránka Guru99 s Page Factory
package PageFactory; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class Guru99Login { /** * All WebElements are identified by @FindBy annotation */ WebDriver driver; @FindBy(name="uid") WebElement user99GuruName; @FindBy(name="password") WebElement password99Guru; @FindBy(className="barone") WebElement titleText; @FindBy(name="btnLogin") WebElement login; public Guru99Login(WebDriver driver){ this.driver = driver; //This initElements method will create all WebElements PageFactory.initElements(driver, this); } //Set user name in textbox public void setUserName(String strUserName){ user99GuruName.sendKeys(strUserName); } //Set password in password textbox public void setPassword(String strPassword){ password99Guru.sendKeys(strPassword); } //Click on login button public void clickLogin(){ login.click(); } //Get the title of Login Page public String getLoginTitle(){ return titleText.getText(); } /** * This POM method will be exposed in test case to login in the application * @param strUserName * @param strPasword * @return */ public void loginToGuru99(String strUserName,String strPasword){ //Fill user name this.setUserName(strUserName); //Fill password this.setPassword(strPasword); //Click Login button this.clickLogin(); } }
Domovská stránka Guru99 s Page Factory
package PageFactory; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class Guru99HomePage { WebDriver driver; @FindBy(xpath="//table//tr[@class='heading3']") WebElement homePageUserName; public Guru99HomePage(WebDriver driver){ this.driver = driver; //This initElements method will create all WebElements PageFactory.initElements(driver, this); } //Get the User name from Home Page public String getHomePageDashboardUserName(){ return homePageUserName.getText(); } }
Guru99 TestCase s konceptem Page Factory
package test; import java.util.concurrent.TimeUnit; import org.openqa.selenium.WebDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.testng.Assert; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import PageFactory.Guru99HomePage; import PageFactory.Guru99Login; public class Test99GuruLoginWithPageFactory { String driverPath = "C:\\geckodriver.exe"; WebDriver driver; Guru99Login objLogin; Guru99HomePage objHomePage; @BeforeTest public void setup(){ System.setProperty("webdriver.gecko.driver", driverPath); driver = new FirefoxDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get("https://demo.guru99.com/V4/"); } /** * This test go to https://demo.guru99.com/V4/ * Verify login page title as guru99 bank * Login to application * Verify the home page using Dashboard message */ @Test(priority=0) public void test_Home_Page_Appear_Correct(){ //Create Login Page object objLogin = new Guru99Login(driver); //Verify login page title String loginPageTitle = objLogin.getLoginTitle(); Assert.assertTrue(loginPageTitle.toLowerCase().contains("guru99 bank")); //login to application objLogin.loginToGuru99("mgr123", "mgr!23"); // go the next page objHomePage = new Guru99HomePage(driver); //Verify home page Assert.assertTrue(objHomePage.getHomePageDashboardUserName().toLowerCase().contains("manger id : mgr123")); } }
Kompletní struktura projektu bude vypadat jako na obrázku:
AjaxElementLocatorFactory
AjaxElementLocatorFactory je koncept líného načítání PageFactory in Selenium. Používá se k nalezení prvků webu pouze tehdy, když jsou prvky použity v jakékoli operaci. Třídě stránky objektu přiřadí časový limit pro WebElements. Jedna z klíčových výhod použití vzoru PageFactory v Selenium je třída AjaxElementLocatorFactory.
Zde, když je na prvku provedena operace, čekání na jeho viditelnost začíná teprve od tohoto okamžiku. Pokud prvek není v daném časovém intervalu nalezen, Testovací případ provedení vyvolá výjimku 'NoSuchElementException'.
Shrnutí
- Objektový model stránky v Selenium WebDriver je návrhový vzor úložiště objektů.
- Selenium objektový model stránky vytváří náš testovací kód udržitelný a znovu použitelný.
- Page Factory je optimalizovaný způsob, jak vytvořit objektové úložiště v konceptu rámce Page Object Model.
- AjaxElementLocatorFactory je koncept líného načítání v Page Factory – návrhový vzor objektu stránky k identifikaci WebElements pouze tehdy, když jsou použity v jakékoli operaci.
stáhněte Selenium Soubory projektu pro ukázku v tomto kurzu