page object model with page factory selenium tutorial
Denne dybdegående vejledning forklarer alt om sideobjektmodel (POM) med sidefabrik ved hjælp af eksempler. Du kan også lære implementeringen af POM i selen:
I denne vejledning vil vi forstå, hvordan man opretter en sideobjektmodel ved hjælp af Page Factory-metoden. Vi vil fokusere på:
- Fabriksklasse
- Sådan oprettes en grundlæggende POM ved hjælp af Page Factory Pattern
- Forskellige annoteringer, der bruges i sidefabrikstilgang
Før vi ser, hvad der er Pagefactory, og hvordan det kan bruges sammen med Page-objektmodellen, lad os forstå, hvad der er Page Object Model, der almindeligvis er kendt som POM.
=> Besøg her for at se Selenium-træningsserien for alle.
Hvad du lærer:
- Hvad er Page Object Model (POM)?
- Hvad er pagefactory?
- POM ved hjælp af Page Factory
- Ofte stillede spørgsmål
- Konklusion
Hvad er Page Object Model (POM)?
Teoretiske terminologier beskriver Sideobjektmodel som et designmønster, der bruges til at oprette et objektlager til de webelementer, der er tilgængelige i applikationen, der testes. Få andre henviser til det som en ramme for Selen-automatisering for den givne applikation, der testes.
Men hvad jeg har forstået ved udtrykket Page Object Model er:
# 1) Det er et designmønster, hvor du har en separat Java-klassefil, der svarer til hver skærm eller side i applikationen. Klassefilen kunne omfatte objektlageret for UI-elementerne såvel som metoder.
#to) Hvis der er enorme webelementer på en side, kan objektlagerklassen for en side adskilles fra klassen, der inkluderer metoder til den tilsvarende side.
Eksempel: Hvis siden Registrer konto har mange inputfelter, kan der være en klasse RegisterAccountObjects.java, der danner objektopbevaringsområdet for UI-elementerne på registerkontosiden.
Der kunne oprettes en separat klassefil RegisterAccount.java, der udvider eller arver RegisterAccountObjects, der inkluderer alle de metoder, der udfører forskellige handlinger på siden.
# 3) Derudover kunne der være en generisk pakke med en {roperties-fil, Excel-testdata og almindelige metoder under en pakke.
Eksempel: DriverFactory, der kunne bruges meget let på alle siderne i applikationen
Forståelse af POM med eksempel
Kontrollere her for at lære mere om POM.
Nedenfor er et øjebliksbillede af websiden:
Ved at klikke på hvert af disse links omdirigeres brugeren til en ny side.
Her er et øjebliksbillede af, hvordan projektstrukturen med Selen er bygget ved hjælp af den side-objektmodel, der svarer til hver side på webstedet. Hver Java-klasse inkluderer objektlager og metoder til at udføre forskellige handlinger på siden.
Derudover vil der være en anden JUNIT eller TestNG eller en Java-klassefil, der påkalder opkald til klassefiler på disse sider.
Hvorfor bruger vi sideobjektmodellen?
Der er en brummer rundt om brugen af denne kraftfulde Selen-ramme kaldet POM eller side-objektmodel. Nu opstår spørgsmålet som “Hvorfor bruge POM?”.
Det enkle svar på dette er, at POM er en kombination af datadrevne, modulære og hybridrammer. Det er en tilgang til systematisk at organisere scripts på en sådan måde, at det gør det let for QA at opretholde koden uden problemer og hjælper også med at forhindre overflødig eller duplikatkode.
For eksempel, hvis der er en ændring i lokaliseringsværdien på en bestemt side, er det meget let at identificere og foretage den hurtige ændring kun i scriptet på den respektive side uden at påvirke koden andetsteds.
Vi bruger konceptet Page Object Model i Selenium Webdriver af følgende årsager:
- Et objektlager oprettes i denne POM-model. Det er uafhængigt af testsager og kan genbruges til et andet projekt.
- Navngivningskonventionen for metoder er meget let, forståelig og mere realistisk.
- Under Side-objektmodellen opretter vi sideklasser, der kan genbruges i et andet projekt.
- Side-objektmodellen er let for de udviklede rammer på grund af dens flere fordele.
- I denne model oprettes separate klasser til forskellige sider i en webapplikation som login-side, startsiden, medarbejder-detaljeside, ændring af password-side osv.
- Hvis der er ændringer i ethvert element på et websted, behøver vi kun foretage ændringer i en klasse og ikke i alle klasser.
- Det designte script er mere genanvendeligt, læsbart og vedligeholdeligt i tilgangen til side-objektmodellen.
- Dens projektstruktur er ret let og forståelig.
- Kan bruge PageFactory i sideobjektmodellen for at initialisere webelementet og gemme elementer i cachen.
- TestNG kan også integreres i tilgangen til Page Object Model.
Implementering af simpel POM i selen
# 1) Scenarie til automatisering
Nu automatiserer vi det givne scenario ved hjælp af Page Object Model.
Scenariet forklares nedenfor:
Trin 1: Start webstedet 'https: //demo.vtiger.com'.
Trin 2: Indtast den gyldige legitimationsoplysninger.
Trin 3: Log ind på siden.
Trin 4: Bekræft startsiden.
Trin 5: Log ud af webstedet.
Trin 6: Luk browseren.
# 2) Selen-scripts til ovenstående scenario i POM
Nu opretter vi POM-strukturen i formørkelse, som forklaret nedenfor:
Trin 1: Opret et projekt i formørkelse - POM-baseret struktur:
a) Opret projekt 'Sideobjektmodel'.
b) Opret 3-pakke under projektet.
- bibliotek
- sider
- test tilfælde
Bibliotek: Under dette sætter vi de koder, der skal kaldes igen og igen i vores testtilfælde som browserstart, skærmbilleder osv. Brugeren kan tilføje flere klasser under det baseret på projektbehovet.
Sider: Under dette oprettes klasser for hver side i webapplikationen og kan tilføje flere sideklasser baseret på antallet af sider i applikationen.
Test tilfælde: Under dette skriver vi login-testsagen og kan tilføje flere testsager efter behov for at teste hele applikationen.
c) Klasser under pakkerne er vist i nedenstående billede.
Trin to: Opret følgende klasser under bibliotekspakken.
Browser.java: I denne klasse er 3 browsere (Firefox, Chrome og Internet Explorer) defineret, og det kaldes i login test case. Baseret på kravet kan brugeren også teste applikationen i forskellige browsere.
package library; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.firefox.FirefoxDriver; import org.openqa.selenium.ie.InternetExplorerDriver; public class Browser { static WebDriver driver; public static WebDriver StartBrowser(String browsername , String url) { // If the browser is Firefox if (browsername.equalsIgnoreCase('Firefox')) { // Set the path for geckodriver.exe System.setProperty('webdriver.firefox.marionette',' E://Selenium//Selenium_Jars//geckodriver.exe '); driver = new FirefoxDriver(); } // If the browser is Chrome else if (browsername.equalsIgnoreCase('Chrome')) { // Set the path for chromedriver.exe System.setProperty('webdriver.chrome.driver','E://Selenium//Selenium_Jars//chromedriver.exe'); driver = new ChromeDriver(); } // If the browser is IE else if (browsername.equalsIgnoreCase('IE')) { // Set the path for IEdriver.exe System.setProperty('webdriver.ie.driver','E://Selenium//Selenium_Jars//IEDriverServer.exe'); driver = new InternetExplorerDriver(); } driver.manage().window().maximize(); driver.get(url); return driver; } }
ScreenShot.java: I denne klasse skrives et screenshot-program, og det kaldes i test tilfælde, når brugeren ønsker at tage et screenshot af, om testen mislykkes eller bestås.
package library; import java.io.File; import org.apache.commons.io.FileUtils; import org.openqa.selenium.OutputType; import org.openqa.selenium.TakesScreenshot; import org.openqa.selenium.WebDriver; public class ScreenShot { public static void captureScreenShot(WebDriver driver, String ScreenShotName) { try { File screenshot=((TakesScreenshot)driver).getScreenshotAs(OutputType. FILE ); FileUtils.copyFile(screenshot, new File('E://Selenium//'+ScreenShotName+'.jpg')); } catch (Exception e) { System. out .println(e.getMessage()); e.printStackTrace(); } } }
Trin 3: Opret sideklasser under Sidepakke.
Hjemmeside.java: Dette er hjemmesideklassen, hvor alle elementerne på hjemmesiden og metoder er defineret.
package pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class HomePage { WebDriver driver; By logout = By.id('p_lt_ctl03_wSOB_btnSignOutLink'); By home = By.id('p_lt_ctl02_wCU2_lblLabel'); //Constructor to initialize object public HomePage(WebDriver dr) { this .driver=dr; } public String pageverify() { return driver.findElement(home).getText(); } public void logout() { driver.findElement(logout).click(); } }
LoginPage.java: Dette er sideklassen Login, hvor alle elementerne på login-siden og metoderne er defineret.
package pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class LoginPage { WebDriver driver; By UserID = By.xpath('//*[contains(@id,'Login1_UserName')]'); By password = By.xpath('//*[contains(@id,'Login1_Password')]'); By Submit = By.xpath('//*[contains(@id,'Login1_LoginButton')]'); //Constructor to initialize object public LoginPage(WebDriver driver) { this .driver = driver; } public void loginToSite(String Username, String Password) { this .enterUsername(Username); this .enterPasssword(Password); this .clickSubmit(); } public void enterUsername(String Username) { driver.findElement(UserID).sendKeys(Username); } public void enterPasssword(String Password) { driver.findElement(password).sendKeys(Password); } public void clickSubmit() { driver.findElement(Submit).click(); } }
Trin 4: Opret testcases til login-scenariet.
LoginTestCase.java: Dette er LoginTestCase-klassen, hvor testsagen udføres. Brugeren kan også oprette flere testsager i henhold til projektets behov.
package testcases; import java.util.concurrent.TimeUnit; import library.Browser; import library.ScreenShot; import org.openqa.selenium.WebDriver; import org.testng.Assert; import org.testng.ITestResult; import org.testng.annotations.AfterMethod; import org.testng.annotations.AfterTest; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; import pages.HomePage; import pages.LoginPage; public class LoginTestCase { WebDriver driver; LoginPage lp; HomePage hp; int i = 0; // Launch of the given browser. @BeforeTest public void browserlaunch() { driver = Browser.StartBrowser('Chrome', 'http://demostore.kenticolab.com/Special-Pages/Logon.aspx'); driver.manage().timeouts().implicitlyWait(30,TimeUnit. SECONDS ); lp = new LoginPage(driver); hp = new HomePage(driver); } // Login to the Site. @Test(priority = 1) public void Login() { lp.loginToSite('gaurav.3n@gmail.com','Test@123'); } // Verifing the Home Page. @Test(priority = 2) public void HomePageVerify() { String HomeText = hp.pageverify(); Assert.assertEquals(HomeText, 'Logged on as'); } // Logout the site. @Test(priority = 3) public void Logout() { hp.logout(); } // Taking Screen shot on test fail @AfterMethod public void screenshot(ITestResult result) { i = i+1; String name = 'ScreenShot'; String x = name+String.valueOf(i); if (ITestResult. FAILURE == result.getStatus()) { ScreenShot.captureScreenShot(driver, x); } } @AfterTest public void closeBrowser() { driver.close(); } }
Trin 5: Udfør “LoginTestCase.java“.
Trin 6: Output af sideobjektmodellen:
- Start Chrome-browseren.
- Demosiden åbnes i browseren.
- Log ind på demo-siden.
- Bekræft startsiden.
- Log ud af webstedet.
- Luk browseren.
Lad os nu udforske det primære koncept i denne tutorial, der fanger opmærksomheden, dvs. “Pagefactory”.
Hvad er pagefactory?
PageFactory er en måde at implementere “Page Object Model” på. Her følger vi princippet om adskillelse af Page Object Repository og testmetoder. Det er et indbygget koncept af Page Object Model, der er meget optimeret.
Lad os nu få mere klarhed over udtrykket Pagefactory.
# 1) For det første giver konceptet kaldet Pagefactory en alternativ måde med hensyn til syntaks og semantik til oprettelse af et objektlager til webelementerne på en side.
#to) For det andet bruger den en lidt anden strategi til initialisering af webelementerne.
# 3) Objektregistret til UI-webelementerne kunne bygges ved hjælp af:
- Almindelig 'POM uden sidefabrik' og,
- Alternativt kan du bruge 'POM med Pagefactory'.
Nedenfor er en billedlig gengivelse af det samme:
Nu vil vi se på alle de aspekter, der adskiller den sædvanlige POM fra POM med Pagefactory.
a) Forskellen i syntaksen for at lokalisere et element ved hjælp af sædvanlig POM vs POM med Pagefactory.
For eksempel Klik på her for at finde det søgefelt, der vises på siden.
POM uden sidefabrik:
# 1) Nedenfor er hvordan du finder søgefeltet ved hjælp af den sædvanlige POM:
WebElement searchNSETxt=driver.findElement(By.id(“searchBox”));
# 2) Nedenstående trin overfører værdien 'investering' i feltet Søg NSE.
searchNSETxt.sendkeys(“investment”);
POM ved hjælp af Pagefactory:
# 1) Du kan finde søgefeltet ved hjælp af Pagefactory som vist nedenfor.
Annotationen @FindBy bruges i Pagefactory til at identificere et element, mens POM uden Pagefactory bruger driver.findElement () metode til at lokalisere et element.
Den anden erklæring for Pagefactory efter @FindBy tildeler en type WebElement klasse, der fungerer nøjagtigt som tildelingen af et elementnavn af typen WebElement-klasse som en returtype for metoden driver.findElement () der bruges i sædvanlig POM (searchNSETxt i dette eksempel).
Vi vil se på @FindBy kommentarer i detaljer i den kommende del af denne vejledning.
@FindBy(id = 'searchBox') WebElement searchNSETxt;
#to) Nedenstående trin overfører værdien 'investering' til NSE-søgefeltet, og syntaksen forbliver den samme som den sædvanlige POM (POM uden Pagefactory).
searchNSETxt.sendkeys(“investment”);
b) Forskellen i strategien for initialisering af webelementer ved brug af sædvanlig POM vs POM med Pagefactory.
Brug af POM uden sidefabrik:
Nedenfor er et kodestykke til at indstille Chrome-driverstien. Der oprettes en WebDriver-instans med navnedriveren, og ChromeDriver tildeles til 'driveren'. Det samme driverobjekt bruges derefter til at starte National Stock Exchange-webstedet, finde searchBox og indtaste strengværdien i feltet.
Det punkt, som jeg vil fremhæve her, er at når det er POM uden sidefabrik, oprettes driverinstansen oprindeligt, og hvert webelement initialiseres frisk hver gang, når der kaldes til dette webelement ved hjælp af driver.findElement () eller driver .findElements ().
Dette er grunden til, med et nyt trin af driver.findElement () for et element, bliver DOM-strukturen igen scannet igennem og opdateret identifikation af elementet udføres på den side.
System.setProperty('webdriver.chrome.driver', 'C:\eclipse-workspace\automationframework\src\test\java\Drivers\chromedriver.exe'); WebDriver driver = new ChromeDriver(); driver.get('http://www.nseindia.com/'); WebElement searchNSETxt=driver.findElement(By.id(“searchBox”)); searchNSETxt.sendkeys(“investment”);
Brug af POM med Pagefactory:
Udover at bruge @FindBy-kommentar i stedet for driver.findElement () -metoden, bruges nedenstående kodestykke yderligere til Pagefactory. Den statiske initElements () -metode i PageFactory-klassen bruges til at initialisere alle UI-elementer på siden, så snart siden indlæses.
public PagefactoryClass(WebDriver driver) { this.driver = driver; PageFactory.initElements(driver, this); }
Ovenstående strategi gør PageFactory-tilgangen lidt anderledes end den sædvanlige POM. I den sædvanlige POM skal webelementet initialiseres eksplicit, mens i Pagefactory-tilgangen initialiseres alle elementerne med initElements () uden eksplicit at initialisere hvert webelement.
For eksempel: Hvis WebElement blev erklæret, men ikke initialiseret i den sædvanlige POM, kastes 'initialiser variabel' -fejl eller NullPointerException. Derfor skal hver WebElement i den sædvanlige POM initialiseres eksplicit. PageFactory kommer med en fordel i forhold til den sædvanlige POM i dette tilfælde.
Lad os ikke initialisere webelementet BDate (POM uden Pagefactory), kan du se, at fejlen 'Initialiser variabel' vises og beder brugeren om at initialisere den til nul, og derfor kan du ikke antage, at elementerne initialiseres implicit ved lokalisering af dem.
Element BDate initialiseret eksplicit (POM uden Pagefactory):
Lad os nu se på et par tilfælde af et komplet program ved hjælp af PageFactory til at udelukke enhver tvetydighed i forståelsen af implementeringsaspektet.
Eksempel 1:
- Gå til 'http://www.nseindia.com/'
- Vælg 'Valutaderivater' i rullemenuen ud for søgefeltet.
- Søg efter 'USDINR'. Bekræft teksten 'US Dollar-Indian Rupee - USDINR' på den resulterende side.
Programstruktur:
- PagefactoryClass.java, der inkluderer et objektopbevaringssted ved hjælp af sidefabrikskoncept for nseindia.com, der er en konstruktør til initialisering af alle webelementer, oprettes, metode selectCurrentDerivative () for at vælge værdi fra rullemenuen Søgefelt, vælg Symbol () for at vælge et symbol på side, der vises næste og verificerer tekst () for at kontrollere, om sideoverskriften er som forventet eller ej.
- NSE_MainClass.java er hovedklassefilen, der kalder alle ovenstående metoder og udfører de respektive handlinger på NSE-webstedet.
PagefactoryClass.java
package com.pagefactory.knowledge; 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.Select; public class PagefactoryClass { WebDriver driver; @FindBy(id = 'QuoteSearch') WebElement Searchbox; @FindBy(id = 'cidkeyword') WebElement Symbol; @FindBy(id = 'companyName') WebElement pageText; public PagefactoryClass(WebDriver driver) { this.driver = driver; PageFactory.initElements(driver, this); } public void selectCurrentDerivative(String derivative) { Select select = new Select(Searchbox); select.selectByVisibleText(derivative); // 'Currency Derivatives' } public void selectSymbol(String symbol) { Symbol.sendKeys(symbol); } public void verifytext() { if (pageText.getText().equalsIgnoreCase('U S Dollar-Indian Rupee - USDINR')) { System.out.println('Page Header is as expected'); } else System.out.println('Page Header is NOT as expected'); } }
NSE_MainClass.java
package com.pagefactory.knowledge; import java.util.List; import java.util.concurrent.TimeUnit; import org.openqa.selenium.By; import org.openqa.selenium.StaleElementReferenceException; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; public class NSE_MainClass { static PagefactoryClass page; static WebDriver driver; public static void main(String[] args) { System.setProperty('webdriver.chrome.driver', 'C:\Users\eclipse-workspace\automation-framework\src\test\java\Drivers\chromedriver.exe'); driver = new ChromeDriver(); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get('https://www.nseindia.com/'); driver.manage().window().maximize(); test_Home_Page_ofNSE(); } public static void test_Home_Page_ofNSE() throws StaleElementReferenceException { page = new PagefactoryClass(driver); page.selectCurrentDerivative('Currency Derivatives'); page.selectSymbol('USD'); List Options = driver.findElements(By.xpath('//span[contains(.,'USD')]')); int count = Options.size(); for (int i = 0; i Eksempel 2:
- Gå til 'https://www.shoppersstop.com/brands'
- Naviger til Haute curry link.
- Kontroller, om Haute Curry-siden indeholder teksten 'Start nyt noget'.
Programstruktur
- shopperstopPagefactory.java, der inkluderer et objektlager ved hjælp af pagefactory-koncept for shoppersstop.com, der er en konstruktør til initialisering af alle webelementer oprettes, metoder lukkerExtraPopup () for at håndtere en pop op-boks, der åbnes, klik på OnHauteCurryLink () for at klikke på Haute Curry Link og verificérStartNewSomething () for at kontrollere, om Haute Curry-siden indeholder teksten 'Start nyt noget'.
- Shopperstop_CallPagefactory.java er hovedklassefilen, der kalder alle ovenstående metoder og udfører de respektive handlinger på NSE-webstedet.
shopperstopPagefactory.java
package com.inportia.automation_framework; import org.openqa.selenium.JavascriptExecutor; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.support.FindBy; import org.openqa.selenium.support.PageFactory; public class shopperstopPagefactory { WebDriver driver; @FindBy(id='firstVisit') WebElement extrapopup; @FindBy(xpath='//img[@src='https://sslimages.shoppersstop.com /sys-master/root/haf/h3a/9519787376670/brandMedia_HauteCurry_logo.png']') WebElement HCLink; @FindBy(xpath='/html/body/main/footer/div[1]/p') WebElement Startnew; public shopperstopPagefactory(WebDriver driver) { this.driver=driver; PageFactory.initElements(driver, this); } public void closeExtraPopup() { extrapopup.click(); } public void clickOnHauteCurryLink() { JavascriptExecutor js = (JavascriptExecutor) driver; js.executeScript('arguments[0].click();',HCLink); js.executeAsyncScript('window.setTimeout(arguments[arguments.length - 1], 10000);'); if(driver.getCurrentUrl().equals('https://www.shoppersstop.com/haute-curry')) { System.out.println('We are on the Haute Curry page'); } else { System.out.println('We are NOT on the Haute Curry page'); } } public void verifyStartNewSomething() { if (Startnew.getText().equalsIgnoreCase('Start Something New')) { System.out.println('Start new something text exists'); } else System.out.println('Start new something text DOESNOT exists'); } }
Shopperstop_CallPagefactory.java
package com.inportia.automation_framework; import java.util.concurrent.TimeUnit; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class Shopperstop_CallPagefactory extends shopperstopPagefactory { public Shopperstop_CallPagefactory(WebDriver driver) { super(driver); // TODO Auto-generated constructor stub } static WebDriver driver; public static void main(String[] args) { System.setProperty('webdriver.chrome.driver', 'C:\eclipse-workspace\automation-framework\src\test\java\Drivers\chromedriver.exe'); driver = new ChromeDriver(); Shopperstop_CallPagefactory s1=new Shopperstop_CallPagefactory(driver); driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); driver.get('https://www.shoppersstop.com/brands'); s1.clickOnHauteCurryLink(); s1.verifyStartNewSomething(); } }
POM ved hjælp af Page Factory
Videoundervisning - POM med sidefabrik
Del I
Del II
En fabriksklasse bruges til at gøre brug af sideobjekter enklere og lettere.
- Først skal vi finde webelementerne ved en kommentar @FindBy i sideklasser .
- Initialiser derefter elementerne ved hjælp af initElements (), når sideklassen startes.
# 1) @FindBy:
@FindBy-annotering bruges i PageFactory til at lokalisere og deklarere webelementerne ved hjælp af forskellige lokaliseringer.Her videregiver vi attributten såvel som dens værdi, der bruges til at lokalisere webelementet til @FindBy-kommentaren, og derefter erklæres WebElement.
Der er to måder, hvorpå kommentaren kan bruges.
For eksempel:
@FindBy(how = How.ID, using='EmailAddress') WebElement Email; @FindBy(id='EmailAddress') WebElement Email;
Førstnævnte er dog standardmetoden til at erklære WebElements.
'Hvordan' er en klasse, og den har statiske variabler som ID, XPATH, CLASSNAME, LINKTEXT osv.
'ved brug af' - At tildele en værdi til en statisk variabel.
I ovenstående eksempel , vi har brugt attributten 'id' til at finde webelementet 'E-mail'. På samme måde kan vi bruge følgende placatorer med @FindBy-kommentarerne:
- className
- css
- navn
- xpath
- tagnavn
- linkText
- partialLinkText
# 2) initElements ():
InitiElements er en statisk metode af PageFactory-klasse, der bruges til at initialisere alle webelementerne, der er lokaliseret ved @FindBy-kommentar. Således er det nemt at starte sideklasser.
initElements(WebDriver driver, java.lang.Class pageObjectClass)
Vi skal også forstå, at POM følger OOPS-principper.
- WebElements erklæres som private medlemsvariabler (Data Hiding).
- Binding af WebElements med tilsvarende metoder (indkapsling).
Trin til at oprette POM ved hjælp af Page Factory Pattern
# 1) Opret en separat Java-klassefil til hver webside.
#to) I hver klasse skal alle WebElements deklareres som variabler (ved hjælp af annotation - @FindBy) og initialiseres ved hjælp af initElement () -metoden. WebElements deklareret skal initialiseres for at blive brugt i handlingsmetoderne.
# 3) Definer tilsvarende metoder, der virker på disse variabler.
Lad os tage et eksempel på et simpelt scenario:
- Åbn URL'en til en applikation.
- Skriv e-mail-adresse og adgangskodedata.
- Klik på knappen Login.
- Bekræft vellykket loginbesked på søgesiden.
Sidelag
Her har vi 2 sider,
- Hjemmeside - Den side, der åbnes, når URL'en indtastes, og hvor vi indtaster dataene til login.
- Søgeside - En side, der vises efter et vellykket login.
I sidelag erklæres hver side i webapplikationen som en separat Java-klasse, og dens lokaliseringer og handlinger er nævnt der.
Trin til oprettelse af POM med realtidseksempel
# 1) Opret en Java-klasse for hver side:
I denne eksempel , vi får adgang til 2 websider, 'Hjem' og 'Søg' -sider.
Derfor opretter vi 2 Java-klasser i Page Layer (eller i en pakke siger com.automation.pages).
Package Name :com.automation.pages HomePage.java SearchPage.java
# 2) Definer WebElements som variabler ved hjælp af Annotation @FindBy:
Vi ville interagere med:
- E-mail, adgangskode, login-knapfelt på startsiden.
- Vellykket besked på søgesiden.
Så vi definerer WebElements ved hjælp af @FindBy
For eksempel: Hvis vi skal identificere EmailAddress ved hjælp af attribut-id, er dens variable erklæring
//Locator for EmailId field @FindBy(how=How.ID,using='EmailId') private WebElementEmailIdAddress;
# 3) Opret metoder til handlinger, der udføres på WebElements.
Nedenstående handlinger udføres på WebElements:
- Skriv handling i feltet E-mail-adresse.
- Skriv handling i feltet Adgangskode.
- Klik på handling på Login-knappen.
For eksempel, Brugerdefinerede metoder oprettes for hver handling på WebElement som,
public void typeEmailId(String Id){ driver.findElement(EmailAddress).sendKeys(Id) }
Her videregives Id'et som en parameter i metoden, da input sendes af brugeren fra hovedtestsagen.
Bemærk :Der skal oprettes en konstruktør i hver klasse i sidelaget for at hente driverinstansen fra hovedklassen i testlaget og også initialisere WebElements (Page Objects), der er erklæret i sideklassen ved hjælp af PageFactory.InitElement () .
Vi starter ikke driveren her, snarere modtages dens forekomst fra hovedklassen, når objektet til klasselaget Sidelag oprettes.
InitElement () - bruges til at initialisere de erklærede WebElements ved hjælp af driverinstans fra hovedklassen. Med andre ord oprettes WebElements ved hjælp af driverinstansen. Først efter WebElements er initialiseret, kan de bruges i metoderne til at udføre handlinger.
To Java-klasser oprettes for hver side som vist nedenfor:
Hjemmeside.java
//package com.automation.pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class HomePage { WebDriver driver; // Locator for Email Address @FindBy(how=How.ID,using='EmailId') private WebElement EmailIdAddress; // Locator for Password field @FindBy(how=How.ID,using='Password ') private WebElement Password; // Locator for SignIn Button @FindBy(how=How.ID,using='SignInButton') private WebElement SignInButton; // Method to type EmailId public void typeEmailId(String Id){ driver.findElement(EmailAddress).sendKeys(Id) } // Method to type Password public void typePassword(String PasswordValue){ driver.findElement(Password).sendKeys(PasswordValue) } // Method to click SignIn Button public void clickSignIn(){ driver.findElement(SignInButton).click() } // Constructor // Gets called when object of this page is created in MainClass.java public HomePage(WebDriver driver) { // 'this' keyword is used here to distinguish global and local variable 'driver' //gets driver as parameter from MainClass.java and assigns to the driver instance in this class this.driver=driver; PageFactory.initElements(driver,this); // Initialises WebElements declared in this class using driver instance. } }
SearchPage.Java
//package com.automation.pages; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; public class SearchPage{ WebDriver driver; // Locator for Success Message @FindBy(how=How.ID,using='Message') private WebElement SuccessMessage; // Method that return True or False depending on whether the message is displayed public Boolean MessageDisplayed(){ Boolean status = driver.findElement(SuccessMessage).isDisplayed(); return status; } // Constructor // This constructor is invoked when object of this page is created in MainClass.java public SearchPage(WebDriver driver) { // 'this' keyword is used here to distinguish global and local variable 'driver' //gets driver as parameter from MainClass.java and assigns to the driver instance in this class this.driver=driver; PageFactory.initElements(driver,this); // Initialises WebElements declared in this class using driver instance. } }
Test lag
Testcases implementeres i denne klasse. Vi opretter en separat pakke siger, com.automation.test og opretter derefter en Java-klasse her (MainClass.java)
Trin til at oprette testsager:
- Initialiser driveren, og åbn applikationen.
- Opret et objekt i PageLayer-klassen (for hver webside), og send driverinstansen som en parameter.
- Brug det oprettede objekt til at ringe til metoderne i PageLayer-klassen (for hver webside) for at udføre handlinger / verifikation.
- Gentag trin 3, indtil alle handlinger er udført, og luk derefter driveren.
//package com.automation.test; import org.openqa.selenium.WebDriver; import org.openqa.selenium.chrome.ChromeDriver; public class MainClass { public static void main(String[] args) { System.setProperty('webdriver.chrome.driver','./exefiles/chromedriver.exe'); WebDriver driver= new ChromeDriver(); driver.manage().window().maximize(); driver.get('URL mentioned here'); // Creating object of HomePage and driver instance is passed as parameter to constructor of Homepage.Java HomePage homePage= new HomePage(driver); // Type EmailAddress homePage.typeEmailId('abc@ymail.com'); // EmailId value is passed as paramter which in turn will be assigned to the method in HomePage.Java // Type Password Value homePage.typePassword('password123'); // Password value is passed as paramter which in turn will be assigned to the method in HomePage.Java // Click on SignIn Button homePage.clickSignIn(); // Creating an object of LoginPage and driver instance is passed as parameter to constructor of SearchPage.Java SearchPage searchPage= new SearchPage(driver); //Verify that Success Message is displayed Assert.assertTrue(searchPage.MessageDisplayed()); //Quit browser driver.quit(); } }
Annotationstypehierarki, der bruges til at deklarere WebElements
Kommentarer bruges til at konstruere en placeringsstrategi for UI-elementerne.
#1) @FindBy
Når det kommer til Pagefactory, fungerer @FindBy som en magisk tryllestav. Det tilføjer al kraft til konceptet. Du er nu opmærksom på, at @FindBy-kommentar i Pagefactory udfører det samme som driver.findElement () i den sædvanlige side-objektmodel. Det bruges til at lokalisere WebElement / WebElements med et kriterium .
#2) @FindBys
Det bruges til at lokalisere WebElement med mere end et kriterium og skal matche alle de givne kriterier. Disse kriterier skal nævnes i et forhold mellem forældre og barn. Med andre ord bruger dette OG betinget forhold til at lokalisere WebElements ved hjælp af de angivne kriterier. Det bruger flere @ FindBy til at definere hvert kriterium.
For eksempel:
HTML-kildekode for et WebElement:
I POM:
@FindBys({ @FindBy(id = 'searchId_1'), @FindBy(name = 'search_field') }) WebElementSearchButton;
I ovenstående eksempel er WebElement 'SearchButton' kun placeret, hvis den er matcher begge kriterierne, hvis id-værdi er 'searchId_1', og navneværdien er 'search_field'. Bemærk, at de første kriterier tilhører et overordnet tag, og det andet kriterium for et underordnet tag.
# 3) @FindAll
Det bruges til at lokalisere WebElement med mere end et kriterium og det skal matche mindst et af de givne kriterier. Dette bruger ELLER betingede forhold for at lokalisere WebElements. Det bruger flere @ FindBy til at definere alle kriterier.
For eksempel:
HTML kildekode:
I POM:
@FindBys({ @FindBy(id = 'UsernameNameField_1'), // doesn’t match @FindBy(name = 'User_Id') //matches @FindBy(className = “UserName_r”) //matches }) WebElementUserName;
I ovenstående eksempel findes WebElement 'Brugernavn, hvis det matcher mindst en af de nævnte kriterier.
# 4) @CacheLookUp
Når WebElement oftere bruges i testtilfælde, ser Selenium op til WebElement, hver gang testscriptet køres. I de tilfælde, hvor visse WebElements bruges globalt til alle TC ( For eksempel, Login-scenarie sker for hver TC), denne kommentar kan bruges til at vedligeholde disse WebElements i cachehukommelsen, når den først læses for første gang.
Dette hjælper igen koden til at køre hurtigere, fordi hver gang den ikke behøver at søge efter WebElement på siden, snarere kan den få sin reference fra hukommelsen.
Dette kan være som et præfiks med en hvilken som helst af @FindBy, @FindBys og @FindAll.
For eksempel:
@CacheLookUp @FindBys({ @FindBy(id = 'UsernameNameField_1'), @FindBy(name = 'User_Id') @FindBy(className = “UserName_r”) }) WebElementUserName;
Bemærk også, at denne kommentar kun skal bruges til WebElements, hvis attributværdi (som xpath, id-navn, klassenavn osv.) Ikke ændrer sig ganske ofte. Når WebElement er placeret for første gang, bevarer den sin reference i cachehukommelsen.
Så så sker der en ændring i WebElement's attribut efter få dage, Selenium vil ikke være i stand til at finde elementet, fordi det allerede har sin gamle reference i sin cachehukommelse og ikke vil overveje den nylige ændring i WebElement.
Mere om PageFactory.initElements ()
Nu hvor vi forstår Pagefactory-strategien om initialisering af webelementerne ved hjælp af InitElements (), lad os prøve at forstå de forskellige versioner af metoden.
Metoden som vi kender tager driverobjektet og det aktuelle klasseobjekt som inputparametre og returnerer sideobjektet ved implicit og proaktivt at initialisere alle elementerne på siden.
I praksis foretrækkes brugen af konstruktøren som vist i ovenstående afsnit frem for de andre måder, hvorpå den anvendes.
Alternative måder at kalde metoden på er:
# 1) I stedet for at bruge “denne” markør kan du oprette det aktuelle klasseobjekt, videregive driverforekomsten til det og kalde den statiske metode initElements med parametre, dvs. driverobjektet og det klasseobjekt, der netop blev oprettet.
public PagefactoryClass(WebDriver driver) { //version 2 PagefactoryClass page=new PagefactoryClass(driver); PageFactory.initElements(driver, page); }
#to) Den tredje måde at initialisere elementer ved hjælp af Pagefactory-klassen er ved hjælp af api kaldet 'refleksion'. Ja, i stedet for at oprette et klasseobjekt med et 'nyt' nøgleord, kan classname.class sendes som en del af inputparameteren initElements ().
public PagefactoryClass(WebDriver driver) { //version 3 PagefactoryClass page=PageFactory.initElements(driver, PagefactoryClass.class); }
Ofte stillede spørgsmål
Q # 1) Hvad er de forskellige lokaliseringsstrategier, der bruges til @FindBy?
Svar: Det enkle svar på dette er, at der ikke findes forskellige lokaliseringsstrategier, der bruges til @FindBy.
De bruger de samme 8 lokaliseringsstrategier, som metoden findElement () i den sædvanlige POM bruger:
- id
- navn
- className
- xpath
- css
- tagnavn
- linkText
- partialLinkText
Q # 2) Er der også forskellige versioner af brugen af @FindBy-kommentarer?
Svar: Når der er et webelement, der skal søges, bruger vi kommentaren @FindBy. Vi vil uddybe de alternative måder at bruge @FindBy sammen med de forskellige lokaliseringsstrategier også.
Vi har allerede set, hvordan man bruger version 1 af @FindBy:
@FindBy(id = 'cidkeyword') WebElement Symbol;
Version 2 af @FindBy er ved at sende inputparameteren som Hvordan og Ved brug af .
Hvordan ser efter lokaliseringsstrategien, hvorved webelementet vil blive identificeret. Nøgleordet ved brug af definerer lokaliseringsværdien.
Se nedenfor for bedre forståelse,
- How.ID søger i elementet ved hjælp af id strategi og det element, den forsøger at identificere, har id = cidkeyword.
@FindBy(how = How.ID, using = ' cidkeyword') WebElement Symbol;
- How.CLASS_NAME søger i elementet ved hjælp af className strategi og det element, den forsøger at identificere, har klasse = ny klasse.
@FindBy(how = How.CLASS_NAME, using = 'newclass') WebElement Symbol;
Q # 3) Er der forskel på de to versioner af @FindBy?
Svar: Svaret er Nej, der er ingen forskel mellem de to versioner. Det er bare, at den første version er den kortere og lettere sammenlignet med den anden version.
Spørgsmål nr. 4) Hvad bruger jeg i siden, hvis der er en liste over webelementer, der skal findes?
Svar: I det sædvanlige sideobjektdesignmønster har vi driver.findElements () til at finde flere elementer, der hører til samme klasse eller tagnavn, men hvordan finder vi sådanne elementer i tilfælde af sideobjektmodel med Pagefactory? Den nemmeste måde at opnå sådanne elementer på er at bruge den samme kommentar @FindBy.
Jeg forstår, at denne linje synes at være en hovedskraber for mange af jer. Men ja, det er svaret på spørgsmålet.
Lad os se på nedenstående eksempel:
Ved hjælp af den sædvanlige sideobjektmodel uden Pagefactory bruger du driver.findElements til at finde flere elementer som vist nedenfor:
private List multipleelements_driver_findelements = driver.findElements (By.class(“last”));
Det samme kan opnås ved hjælp af sideobjektmodellen med Pagefactory som angivet nedenfor:
@FindBy (how = How.CLASS_NAME, using = 'last') private List multipleelements_FindBy;
Dybest set er det at knytte elementerne til en liste af typen WebElement, uanset om Pagefactory er blevet brugt eller ej, mens elementerne identificeres og lokaliseres.
Spørgsmål nr. 5) Kan både design af sideobjekt uden pagefactory og med Pagefactory bruges i det samme program?
Svar: Ja, både sideobjektdesignet uden Pagefactory og med Pagefactory kan bruges i det samme program. Du kan gå igennem programmet nedenfor i Svar på spørgsmål nr. 6 for at se, hvordan begge bruges i programmet.
En ting at huske er, at Pagefactory-konceptet med cachelagret funktion bør undgås på dynamiske elementer, mens sideobjektdesign fungerer godt for dynamiske elementer. Pagefactory passer dog kun til statiske elementer.
Q # 6) Er der alternative måder at identificere elementer på baggrund af flere kriterier?
sundhedsdomæne viden til testere pdf
Svar: Alternativet til at identificere elementer baseret på flere kriterier er at bruge kommentarerne @FindAll og @FindBys. Disse bemærkninger hjælper med at identificere enkelte eller flere elementer afhængigt af de værdier, der er hentet fra de kriterier, der er sendt i den.
# 1) @FindAll:
@FindAll kan indeholde flere @FindBy og returnerer alle de elementer, der matcher alle @FindBy på en enkelt liste. @FindAll bruges til at markere et felt på et sideobjekt for at indikere, at opslag skal bruge en række @FindBy-tags. Derefter søger det efter alle elementer, der matcher ethvert FindBy-kriterium.
Bemærk, at elementerne ikke garanteres at være i dokumentrækkefølge.
Syntaksen for at bruge @FindAll er som nedenfor:
@FindAll( { @FindBy(how = How.ID, using = 'foo'), @FindBy(className = 'bar') } )
Forklaring: @FindAll søger og identificerer separate elementer, der overholder hvert af @FindBy-kriterierne, og viser dem. I ovenstående eksempel søger det først i et element, hvis id = ”foo” og identificerer derefter det andet element med className = ”bar”.
Hvis vi antager, at der var identificeret et element for hvert FindBy-kriterium, vil @FindAll resultere i, at der henholdsvis vises 2 elementer. Husk, at der kunne være flere elementer identificeret for hvert kriterium. Således, med enkle ord, @ FindAlle fungerer svarende til ELLER operatør på @FindBy-kriterierne bestået.
#2) @FindBys:
FindBys bruges til at markere et felt på et sideobjekt for at indikere, at opslag skal bruge en række @FindBy-tags i en kæde som beskrevet i ByChained. Når de krævede WebElement-objekter skal matche alle de givne kriterier, skal du bruge @FindBys-kommentar.
Syntaksen for at bruge @FindBys er som nedenfor:
@FindBys( { @FindBy(name=”foo”) @FindBy(className = 'bar') } )
Forklaring: @FindBys søger og identificerer elementer, der overholder alle @FindBy-kriterierne, og viser dem. I ovenstående eksempel søger det i elementer, hvis navn = ”foo” og className = ”bar”.
@FindAll vil resultere i en liste over 1 element, hvis vi antager, at der var et element identificeret med navnet og className i de givne kriterier.
Hvis der ikke er et element, der opfylder alle beståede FindBy-betingelser, vil resultatet af @FindBys være nul elementer. Der kunne være en liste over webelementer identificeret, hvis alle betingelser opfylder flere elementer. Med enkle ord, @ FindBys fungerer svarende til OG operatør på @FindBy-kriterierne bestået.
Lad os se implementeringen af al den ovennævnte kommentar gennem et detaljeret program:
Vi vil ændre www.nseindia.com-programmet, der er givet i det foregående afsnit for at forstå implementeringen af kommentarerne @FindBy, @FindBys og @FindAll
# 1) Objektregistret for PagefactoryClass opdateres som nedenfor:
Vis ny liste = driver.findElements (By.tagName (“a”));
@FindBy (hvordan = hvordan. TAG_NAME , ved hjælp af = “a”)
privat Liste findbyvalue;
@FindAll ({ @FindBy (className = “sel”), @FindBy (xpath = ”// a [@ id =’ tab5 ′] ”)})
privat Liste findallvalue;
@FindBys ({ @FindBy (className = “sel”), @FindBy (xpath = ”// a [@ id =’ tab5 ′] ”)})
privat Liste findbysvalue;
# 2) En ny metode seeHowFindWorks () er skrevet i PagefactoryClass og påberåbes som den sidste metode i hovedklassen.
Metoden er som nedenfor:
private void seeHowFindWorks() { System.out.println('driver.findElements(By.tagName()) '+newlist.size()); System.out.println('count of @FindBy- list elements '+findbyvalue.size()); System.out.println('count of @FindAll elements '+findallvalue.size()); for(int i=0;i Nedenfor er resultatet vist på konsolvinduet efter udførelse af programmet:
Lad os nu prøve at forstå koden i detaljer:
# 1) Gennem designmønsteret for sideobjektet identificerer elementet 'newlist' alle tags med anker 'a'. Med andre ord får vi et antal af alle links på siden.
Vi lærte, at sidefabrikken @FindBy gør det samme job som driver.findElement (). Elementet findbyvalue er oprettet for at få optællingen af alle links på siden gennem en søgestrategi med et sidefabrikerende koncept.
Det viser sig at være korrekt, at både driver.findElement () og @FindBy gør det samme job og identificerer de samme elementer. Hvis du ser på skærmbilledet af det resulterende konsolvindue ovenfor, er antallet af links identificeret med elementet newlist og findbyvalue ens, dvs. 299 links fundet på siden.
Resultatet viste som nedenfor:
driver.findElements(By.tagName()) 299 count of @FindBy- list elements 299
#to) Her uddyber vi arbejdet med @FindAll-kommentaren, der vedrører listen over webelementerne med navnet findallvalue.
Når man ser nøje på hvert @ FindBy-kriterium i @ Find alle-annotationen, søger det første @ Find kriterier efter elementer med className = 'sel' og det andet @ Find kriterier søger efter et specifikt element med XPath = “// a [@ id = 'tab5']
Lad os nu trykke på F12 for at inspicere elementerne på siden nseindia.com og få visse klarheder på elementer, der svarer til @FindBy-kriterierne.
Der er to elementer på siden, der svarer til className = ”sel”:
til) Elementet 'Fundamentals' har listetegnet, dvs.
med className = ”sel”. Se øjebliksbillede nedenfor
b) Et andet element 'Ordrebog' har en XPath med et ankermærke, der har klassens navn som 'sel'.
c) Den anden @ FindBy med XPath har et ankermærke, hvis id er “ fane 5 ”. Der er kun et element identificeret som reaktion på søgningen, som er grundlæggende.
Se øjebliksbillede nedenfor:
Da nseindia.com-testen blev udført, fik vi antallet af elementer, der blev søgt efter.
@FindAll som 3. Elementerne til findallvalue, når de blev vist, var: Fundamentals som 0thindekselement, ordrebog som 1St.indekselement og Fundamentals igen som 2ndindekselement. Vi har allerede lært, at @FindAll identificerer elementer for hvert @ FindBy-kriterium separat.
I henhold til den samme protokol identificerede den for den første kriteriesøgning, dvs. className = ”sel”, to elementer, der opfylder betingelsen, og den hentede 'Fundamentals' og 'Order Book'.
Derefter flyttede det til det næste @ FindBy-kriterium og i henhold til xpath givet for det andet @ FindBy kunne det hente elementet 'Fundamentals'. Dette er grunden til, at det endelig identificerede henholdsvis 3 elementer.
Således får det ikke elementerne, der opfylder nogen af @FindBy-betingelserne, men det behandler hver af @FindBy-enhederne separat og identificerer elementerne ligeledes. I det aktuelle eksempel så vi også, at det ikke ser, om elementerne er unikke ( For eksempel. Elementet 'Fundamentals' i dette tilfælde, der vises to gange som en del af resultatet af de to @ FindBy-kriterier)
# 3) Her uddyber vi arbejdet med @FindBys-kommentaren, der vedrører listen over webelementerne med navnet findbysvalue. Også her søger det første @ FindBy-kriterier efter elementer med className = ’sel’, og det andet @ Find Find kriterier søger efter et bestemt element med xpath = “// a [@ id =” tab5 ”).
Nu da vi ved, er de elementer, der er identificeret for den første @ FindBy-betingelse, 'Fundamentals' og 'Order Book', og det i det andet @ FindBy-kriterium er 'Fundamentals'.
Så hvordan vil @FindBys resulterende være anderledes end @FindAll? Vi lærte i det foregående afsnit, at @FindBys svarer til AND-betinget operatør, og det ser derfor ud til et element eller listen over elementer, der opfylder alle @FindBy-betingelsen.
Som i vores nuværende eksempel er værdien 'Fundamentals' det eneste element, der har class = 'sel' og id = 'tab5', der opfylder begge betingelser. Dette er grunden til, at @FindBys-størrelse i testtaske er 1, og det viser værdien som 'Grundlæggende'.
Caching af elementerne i sidefabrik
Hver gang en side indlæses, bliver alle elementerne på siden slået op igen ved at påkalde et opkald via @FindBy eller driver.findElement (), og der er en ny søgning efter elementerne på siden.
Det meste af tiden, når elementerne er dynamiske eller ændrer sig under kørselstid, især hvis de er AJAX-elementer, er det helt sikkert fornuftigt, at der med hver sideindlæsning er en ny søgning efter alle elementerne på siden.
Når websiden har statiske elementer, kan caching af elementet hjælpe på flere måder. Når elementerne er cachelagret, behøver det ikke at finde elementerne igen, når siden indlæses, men kan i stedet henvise til det cachelagrede elementlager. Dette sparer meget tid og øger bedre ydelse.
Pagefactory giver denne funktion til caching af elementerne ved hjælp af en kommentar @CacheLookUp .
Annotationen beder driveren om at bruge den samme forekomst af lokalisatoren fra DOM til elementerne og ikke at søge dem igen, mens initElements-metoden til pagefactory fremtrædende bidrager til lagring af det cachelagrede statiske element. Initiativerne udfører elementernes cachearbejde.
Dette gør det sidefabrikerende koncept specielt i forhold til det almindelige design af mønsteret til sidegenstand. Det kommer med sine egne fordele og ulemper, som vi vil diskutere lidt senere. For eksempel er login-knappen på Facebook-hjemmesiden et statisk element, der kan cachelagres og er et ideelt element, der skal cachelagres.
Lad os nu se på, hvordan vi implementerer kommentaren @CacheLookUp
Du skal først importere en pakke til Cachelookup som nedenfor:
import org.openqa.selenium.support.CacheLookup
Nedenfor er uddraget, der viser definitionen af et element ved hjælp af @CacheLookUp. Så snart UniqueElement søges for første gang, gemmer initElement () den cachelagrede version af elementet, så næste gang driveren ikke ser efter elementet i stedet for den henviser til den samme cache og udfører handlingen på elementet til højre væk.
@FindBy(id = 'unique') @CacheLookup private WebElement UniqueElement;
Lad os nu se gennem et faktisk program for, hvordan handlinger på det cachelagrede webelement er hurtigere end det på det ikke-cachelagrede webelement:
Forbedring af nseindia.com-programmet yderligere har jeg skrevet en anden ny metode monitorPerformance (), hvor jeg opretter et cache-element til søgefeltet og et ikke-cache-element til det samme søgefelt.
Derefter forsøger jeg at få elementets tagname 3000 gange for både det cachelagrede og det ikke-cachelagrede element og prøver at måle den tid, det tager at fuldføre opgaven af både det cachelagrede og ikke-cachelagrede element.
Jeg har overvejet 3000 gange, så vi er i stand til at se en synlig forskel i timingen for de to. Jeg forventer, at det cachelagrede element skal færdiggøre at få tagnamnet 3000 gange på kortere tid sammenlignet med det for det ikke-cachelagrede element.
Vi ved nu, hvorfor det cachelagrede element skal fungere hurtigere, dvs. at føreren bliver instrueret til ikke at slå elementet op efter den første opslag, men fortsætte med at arbejde på det, og det er ikke tilfældet med det ikke-cachelagrede element, hvor elementopslag er gjort for alle 3000 gange, og derefter udføres handlingen på det.
Nedenfor er koden til metoden monitorPerformance ():
private void monitorPerformance() { //non cached element long NoCache_StartTime = System.currentTimeMillis(); for(int i = 0; i <3000; i ++) { Searchbox.getTagName(); } long NoCache_EndTime = System.currentTimeMillis(); long NoCache_TotalTime=(NoCache_EndTime-NoCache_StartTime)/1000; System.out.println('Response time without caching Searchbox ' + NoCache_TotalTime+ ' seconds'); //cached element long Cached_StartTime = System.currentTimeMillis(); for(int i = 0; i < 3000; i ++) { cachedSearchbox.getTagName(); } long Cached_EndTime = System.currentTimeMillis(); long Cached_TotalTime=(Cached_EndTime - Cached_StartTime)/1000; System.out.println('Response time by caching Searchbox ' + Cached_TotalTime+ ' seconds'); }
Ved udførelse ser vi nedenstående resultat i konsolvinduet:
I henhold til resultatet afsluttes opgaven på det ikke-cachelagrede element i 82 sekunder, mens den tid, det tog at fuldføre opgaven på det cachelagrede element, kun var 37 sekunder. Dette er faktisk en synlig forskel i responstiden for både det cachelagrede og ikke-cachelagrede element.
Q # 7) Hvad er fordele og ulemper ved kommentaren @CacheLookUp i Pagefactory-konceptet?
Svar:
Fordele @CacheLookUp og situationer, der er mulige for dets anvendelse:
@CacheLookUp er mulig, når elementerne er statiske eller slet ikke ændres, mens siden indlæses. Sådanne elementer ændrer ikke køretiden. I sådanne tilfælde tilrådes det at bruge kommentaren til at forbedre den samlede hastighed for testudførelsen.
Ulemper ved kommentaren @CacheLookUp:
Den største ulempe ved at have cachelagrede elementer med kommentaren er frygt for ofte at få StaleElementReferenceExceptions.
Dynamiske elementer opdateres ganske ofte med dem, der er modtagelige for ændringer hurtigt over et par sekunder eller minutter af tidsintervallet.
Nedenfor er nogle få sådanne forekomster af de dynamiske elementer:
- At have et stopur på websiden, der holder timeren opdateret hvert sekund.
- En ramme, der konstant opdaterer vejrrapporten.
- En side, der rapporterer de live Sensex-opdateringer.
Disse er slet ikke ideelle eller gennemførlige til brugen af kommentaren @CacheLookUp. Hvis du gør det, risikerer du at få undtagelsen fra StaleElementReferenceExceptions.
Ved cachelagring af sådanne elementer ændres elementernes DOM under testudførelse, men driveren ser efter den version af DOM, der allerede var gemt under cache. Dette gør det uaktuelle element, der skal slås op af føreren, som ikke længere findes på websiden. Dette er grunden til, at StaleElementReferenceException kastes.
Fabriksklasser:
Pagefactory er et koncept bygget på flere fabriksklasser og grænseflader. Vi lærer om et par fabriksklasser og grænseflader her i dette afsnit. Få af hvilke vi vil se på er AjaxElementLocatorFactory , ElementLocatorFactory og StandardElementFactory.
Har vi nogensinde spekuleret på, om Pagefactory giver nogen måde at inkorporere Implicit eller Explicit vent på elementet, indtil en bestemt tilstand er opfyldt ( Eksempel: Indtil et element er synligt, aktiveret, klikbart osv.)? Hvis ja, her er et passende svar på det.
AjaxElementLocatorFactory er en af de væsentligste bidragydere blandt alle fabriksklasser. Fordelen ved AjaxElementLocatorFactory er, at du kan tildele en timeout-værdi for et webelement til Objekt-sideklassen.
Selvom Pagefactory ikke indeholder en eksplicit ventefunktion, er der dog en variant til implicit ventetid ved hjælp af klassen AjaxElementLocatorFactory . Denne klasse kan bruges inkorporeret, når applikationen bruger Ajax-komponenter og -elementer.
Sådan implementerer du det i koden. Når vi bruger metoden initElements () inden for konstruktøren, kan vi bruge AjaxElementLocatorFactory til at give en implicit ventetid på elementerne.
PageFactory.initElements(driver, this); can be replaced with PageFactory.initElements( new AjaxElementLocatorFactory(driver, 20), this);
Ovenstående anden linje i koden indebærer, at føreren skal indstille en timeout på 20 sekunder for alle elementerne på siden, når hver af dens belastninger, og hvis noget af elementet ikke findes efter en ventetid på 20 sekunder, kastes 'NoSuchElementException' for det manglende element.
Du kan også definere ventetiden som nedenfor:
public pageFactoryClass(WebDriver driver) { ElementLocatorFactory locateMe = new AjaxElementLocatorFactory(driver, 30); PageFactory.initElements(locateMe, this); this.driver = driver; }
Ovenstående kode fungerer perfekt, fordi klassen AjaxElementLocatorFactory implementerer grænsefladen ElementLocatorFactory.
Her refererer overordnet interface (ElementLocatorFactory) til objektet i underklassen (AjaxElementLocatorFactory). Derfor bruges Java-konceptet 'upcasting' eller 'runtime polymorphism', mens der tildeles en timeout ved hjælp af AjaxElementLocatorFactory.
Med hensyn til hvordan det fungerer teknisk opretter AjaxElementLocatorFactory først en AjaxElementLocator ved hjælp af en SlowLoadableComponent, der muligvis ikke er færdig med at indlæse, når belastningen () vender tilbage. Efter et opkald til at indlæse () skal metoden isLoaded () fortsætte med at mislykkes, indtil komponenten er fuldt indlæst.
Med andre ord vil alle elementerne blive slået op frisk hver gang, når et element er tilgængeligt i koden ved at påkalde et opkald til locator.findElement () fra klassen AjaxElementLocator, som derefter anvender en timeout, indtil den indlæses gennem SlowLoadableComponent-klassen.
Derudover, efter tildeling af timeout via AjaxElementLocatorFactory, vil elementerne med @CacheLookUp-kommentar ikke længere blive cachelagret, da kommentaren ignoreres.
Der er også en variation i hvordan du kan ring til initiativer () metode og hvordan du burde ikke ring til AjaxElementLocatorFactory for at tildele timeout for et element.
# 1) Du kan også angive et elementnavn i stedet for driverobjektet som vist nedenfor i initElements () -metoden:
PageFactory.initElements( , this);
initElements () -metoden i ovenstående variant påkalder internt et opkald til klassen DefaultElementFactory, og DefaultElementFactory's konstruktør accepterer SearchContext-interfaceinterfaceobjektet som en inputparameter. Webdriverobjekt og et webelement hører begge til SearchContext-grænsefladen.
I dette tilfælde initialiseres metoden initElements () på forhånd kun til det nævnte element, og ikke alle elementer på websiden initialiseres.
#to) Men her er et interessant twist til denne kendsgerning, der angiver, hvordan du ikke skal kalde AjaxElementLocatorFactory-objekt på en bestemt måde. Hvis jeg bruger ovennævnte variant af initElements () sammen med AjaxElementLocatorFactory, vil den mislykkes.
Eksempel: Nedenstående kode, dvs. at sende elementnavn i stedet for driverobjekt til AjaxElementLocatorFactory-definitionen, fungerer ikke, da konstruktøren til AjaxElementLocatorFactory-klassen kun tager webdriverobjekt som inputparameter, og derfor vil SearchContext-objektet med webelement ikke fungere for det.
PageFactory.initElements(new AjaxElementLocatorFactory(, 10), this);
Spørgsmål nr. 8) Bruger man sidefabrikken en mulig mulighed i forhold til det normale mønster for sideobjektdesign?
Svar: Dette er det vigtigste spørgsmål, som folk har, og det er derfor, jeg tænkte på at tage fat på det i slutningen af vejledningen. Vi kender nu 'ind og ud' om Pagefactory startende fra dets koncepter, anvendte annoteringer, yderligere funktioner, det understøtter, implementering via kode, fordele og ulemper.
Alligevel forbliver vi med dette vigtige spørgsmål, at hvis sidefabrikken har så mange gode ting, hvorfor skal vi ikke holde fast ved brugen heraf.
Pagefactory kommer med konceptet CacheLookUp, som vi så ikke er muligt for dynamiske elementer som værdier for elementet bliver ofte opdateret. Så sidefaktorisk uden CacheLookUp, er det en god mulighed at gå? Ja, hvis xpaths er statiske.
Imidlertid er undergangen, at den moderne tidsapplikation er fyldt med tunge dynamiske elementer, hvor vi kender design af sideobjekt uden sidefabrik fungerer i sidste ende godt, men fungerer sidefabrikkskonceptet lige så godt med dynamiske xpaths? Måske ikke. Her er et hurtigt eksempel:
På nseindia.com-websiden ser vi en tabel som angivet nedenfor.
Tabellen xpath er
'//*[@id='tab9Content']/table/tbody/tr[+count+]/td[1]'
Vi ønsker at hente værdier fra hver række til den første kolonne 'Køb antal'. For at gøre dette bliver vi nødt til at øge række tælleren, men kolonneindekset forbliver 1. Der er ingen måde, hvorpå vi kan overføre denne dynamiske XPath i @FindBy-kommentaren, da kommentaren accepterer værdier, der er statiske, og ingen variabler kan videregives det.
Her er hvor sidefabrikken fejler helt, mens den sædvanlige POM fungerer godt med den. Du kan nemt bruge en for-løkke til at forøge rækkeindeks ved hjælp af sådanne dynamiske xpaths i metoden driver.findElement ().
Konklusion
Page Object Model er et designkoncept eller mønster, der anvendes i Selenium-automatiseringsrammen.
Navngivning af konvektion af metoder er brugervenlig i Page Object Model. Koden i POM er let at forstå, genanvendelig og vedligeholdelig. I POM, hvis der er nogen ændringer i webelementet, er det nok at foretage ændringerne i sin respektive klasse i stedet for at redigere alle klasser.
Pagefactory ligesom den sædvanlige POM er et vidunderligt koncept at anvende. Vi skal dog vide, hvor den sædvanlige POM er mulig, og hvor Pagefactory passer godt. I de statiske applikationer (hvor både XPath og elementerne er statiske) kan Pagefactory også implementeres med ekstra fordele ved bedre ydelse.
Alternativt, når applikationen involverer både dynamiske og statiske elementer, kan du muligvis have en blandet implementering af pom med Pagefactory, og det uden Pagefactory i henhold til gennemførligheden for hvert webelement.
Forfatter: Denne vejledning er skrevet af Shobha D. Hun arbejder som projektledelse og har 9+ års erfaring inden for manuel, automatisering (Selenium, IBM Rational Functional Tester, Java) og API-test (SOAPUI og være sikker på Java) .
Nu over til dig for yderligere implementering af Pagefactory.
Happy Exploring !!!
=> Besøg her for at lære selen fra bunden.
Anbefalet læsning
- 30+ bedste selen-tutorials: Lær selen med rigtige eksempler
- Effektiv Selen Scripting og fejlfinding af scenarier - Selen Tutorial # 27
- Fejlfinding af selen-scripts med logfiler (Log4j-vejledning) - Selen-tutorial # 26
- Introduktion til JUnit Framework og dens anvendelse i Selenium Script - Selen Tutorial # 11
- 7 faktorer, der påvirker testestimering af selen-automatiseringsprojekt - Selen-tutorial # 32
- Påstande i selen ved hjælp af Junit og TestNG Frameworks
- Sådan bruges TestNG Framework til oprettelse af selen-scripts - TestNG Selen Tutorial # 12
- Lær hvordan du bruger TestNG-kommentarer i selen (med eksempler)