Modello di oggetti di pagina e fabbrica in Selenium

Che cos'è il modello a oggetti di pagina?

Modello oggetto pagina (POM) è un modello di progettazione, comunemente utilizzato nell'automazione dei test, che crea un repository di oggetti per elementi dell'interfaccia utente Web. Il vantaggio del modello è che riduce la duplicazione del codice e migliora la manutenzione dei test.

Secondo questo modello, per ogni pagina web nell'applicazione, dovrebbe esserci una classe di pagina corrispondente. Questa classe Page identificherà i WebElements di quella pagina web e contiene anche i metodi Page che eseguono operazioni su tali WebElements. Il nome di questi metodi deve essere fornito in base all'attività che stanno eseguendo, ovvero, se un caricatore è in attesa che venga visualizzato il gateway di pagamento, il nome del metodo POM può essere waitForPaymentScreenDisplay().

Modello a oggetti della pagina

Perché il modello a oggetti della pagina?

Avvio di un'automazione dell'interfaccia utente in Selenium WebDriver NON è un compito difficile. Hai solo bisogno di trovare elementi, eseguire operazioni su di essi.

Considera questo semplice script per accedere a un sito web

Modello a oggetti della pagina

Come puoi osservare, tutto ciò che stiamo facendo è trovare elementi e riempire valori per tali elementi.

Questa è una piccola sceneggiatura. La manutenzione degli script sembra semplice. Ma con il tempo la suite di test crescerà. Man mano che aggiungi sempre più righe al tuo codice, le cose diventano difficili.

Il problema principale con la manutenzione degli script è che se 10 script diversi utilizzano lo stesso elemento della pagina, con qualsiasi modifica in quell'elemento, è necessario modificare tutti e 10 gli script. Ciò richiede tempo ed è soggetto a errori.

Un approccio migliore alla manutenzione degli script è creare un file di classe separato che trovi gli elementi web, li riempia o li verifichi. Questa classe può essere riutilizzata in tutti gli script che utilizzano quell'elemento. In futuro, se si verifica una modifica nell'elemento web, dovremo apportare la modifica solo in 1 file di classe e non in 10 script diversi.

Questo approccio è chiamato Page Object Model in Selenium. Aiuta a rendere il codice più leggibile, manutenibile e riutilizzabile.

Modello a oggetti della pagina

Vantaggi del POM

  1. Page Object Design Pattern afferma che le operazioni e i flussi nell'interfaccia utente dovrebbero essere separati dalla verifica. Questo concetto rende il nostro codice più pulito e facile da capire.
  2. Il secondo vantaggio è che il repository di oggetti è indipendente dai casi di test, quindi possiamo utilizzare lo stesso repository di oggetti per uno scopo diverso con strumenti diversi. Ad esempio, possiamo integrare il Page Object Model in Selenium con TestNG/JUnit per funzionale Testing e allo stesso tempo con JBehave/Cucumber per le prove di accettazione.
  3. Il codice diventa meno numeroso e ottimizzato grazie ai metodi di pagina riutilizzabili nelle classi POM.
  4. I metodi ottengono nomi più realistici che possono essere facilmente mappati con l'operazione che avviene nell'interfaccia utente. cioè se dopo aver cliccato sul pulsante arriviamo alla home page, il nome del metodo sarà come 'gotoHomePage()'.

Come implementare il POM?

POM semplice:

È la struttura di base del framework del modello a oggetti di pagina in cui tutti gli elementi Web del file funzione AUT e il metodo che opera su questi elementi Web vengono mantenuti all'interno di un file di classe. Un'attività come la verifica dovrebbe essere separata come parte dei metodi di test.

Implementare il POM

Esempio completo

Caso di prova: Vai al sito dimostrativo di Guru99.

Passaggio 1) Vai al sito demo di Guru99

Implementare il POM

Passaggio 2) Nella home page verificare che sia presente il testo "Guru99 Bank".

Implementare il POM

Passaggio 3) Accedi all'applicazione

Implementare il POM

Passaggio 4) Verifica che la home page contenga il testo "ID manager: demo"

Implementare il POM

Qui abbiamo a che fare con 2 pagine

  1. Pagina di login
  2. Home Page (mostrata una volta effettuato l'accesso)

Di conseguenza, creiamo 2 POM in Selenium classi

Guru99 Pagina di accesso 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();        
    }

}

Guru99 Home Page 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 POM semplice in Selenium Caso di prova

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"));

    }

In cosa consiste Page Factory Selenium?

Pagina Fabbrica in Selenium è un concetto di framework Page Object Model integrato per Selenium WebDriver ma è molto ottimizzato. Viene utilizzato per l'inizializzazione degli oggetti Page o per creare un'istanza dell'oggetto Page stesso. Viene utilizzato anche per inizializzare gli elementi della classe Page senza utilizzare "FindElement/s".

Anche qui seguiamo il concetto di separazione tra Page Object Repository e Test Methods. Inoltre, con l'aiuto della classe PageFactory in Selenium, usiamo le annotazioni @FindBy per trovare WebElement. Usiamo il metodo initElements per inizializzare gli elementi web

Pagina Fabbrica in Selenium

@FindBy può accettare tagName, partialLinkText, nome, linkText, id, css, className, xpath come attributi.

Diamo un'occhiata allo stesso esempio di cui sopra utilizzando Page Factory

Pagina di accesso di Guru99 con 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();           

    }

}

Home page di Guru99 con 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 con il concetto di 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"));

    }

}

La struttura completa del progetto sarà simile al diagramma:

Pagina Fabbrica in Selenium

AjaxElementLocatorFactory

AjaxElementLocatorFactory è un concetto di caricamento lento di PageFactory in Selenium. Viene utilizzato per trovare gli elementi web solo quando gli elementi vengono utilizzati in qualsiasi operazione. Assegna un timeout per WebElements alla classe della pagina dell'oggetto. Uno dei principali vantaggi dell'utilizzo del pattern PageFactory in Selenium è la classe AjaxElementLocatorFactory.

Ecco che quando viene eseguita un'operazione su un elemento l'attesa per la sua visibilità inizia solo da quel momento. Se l'elemento non viene trovato nell'intervallo di tempo specificato, Test Case l'esecuzione genererà l'eccezione "NoSuchElementException".

Fabbrica di localizzazione di elementi Ajax

Sommario

  1. Modello oggetto pagina in Selenium WebDriver è un modello di progettazione di repository di oggetti.
  2. Selenium il modello a oggetti della pagina crea il nostro codice di test manutenibile, riutilizzabile.
  3. Page Factory è un modo ottimizzato per creare repository di oggetti nel concetto di framework Page Object Model.
  4. AjaxElementLocatorFactory è un concetto di caricamento lento in Page Factory: modello di progettazione di oggetti di pagina per identificare WebElements solo quando vengono utilizzati in qualsiasi operazione.

Scarica la Selenium File di progetto per la demo in questo tutorial

Per saperne di più leggi di più