Ricerca…


introduzione

Un ruolo significativo nell'automazione di siti Web e applicazioni Web implica l'identificazione di elementi sullo schermo e l'interazione con essi. Gli oggetti si trovano nel Selenio attraverso l'uso di localizzatori e la classe By . Questi locatori e interazioni sono posti all'interno di Page Objects come una buona pratica per evitare il codice duplicato e facilitare la manutenzione. Incapsula WebElements e suppone che contenga comportamenti e restituisca informazioni sulla pagina (o parte di una pagina in un'app Web).

Osservazioni

Il modello a oggetti di pagina è un modello in cui scriviamo classi orientate agli oggetti che fungono da interfaccia per una particolare vista della pagina web. Usiamo i metodi di quella classe di pagina per eseguire l'azione richiesta. Pochi anni fa, stavamo manipolando il codice HTML della pagina web direttamente nelle classi di test, il che era molto difficile da mantenere insieme ai cambiamenti apportati all'interfaccia utente.

Tuttavia, il fatto che il tuo codice sia organizzato in un modello di oggetto della pagina fornisce un'API specifica dell'applicazione, che consente di manipolare gli elementi della pagina senza scavare attorno all'HTML. La semplice Rue of thumb dice che l'oggetto della tua pagina dovrebbe avere tutto ciò che un umano può fare su quella pagina web. Ad esempio, per accedere al campo di testo su una pagina Web, è necessario un metodo per ottenere il testo e restituire la stringa dopo aver apportato tutte le modifiche.

Pochi punti importanti da tenere a mente durante la progettazione degli oggetti della pagina:

  1. L'oggetto della pagina di solito non dovrebbe costruire solo per le pagine, ma dovresti preferirlo per costruire elementi significativi della pagina. Ad esempio, una pagina con più schede per mostrare diversi grafici dei tuoi accademici dovrebbe avere lo stesso numero di pagine del conteggio delle schede.

  2. La navigazione da una vista ad un'altra dovrebbe restituire l'istanza delle classi di pagine.

  3. I metodi di utilità che devono essere presenti solo per una vista o pagina Web specifica dovrebbero appartenere solo a quella classe di pagine.

  4. I metodi di asserzione non dovrebbero essere presi in considerazione dalle classi di pagine, puoi avere metodi per restituire booleano ma non verificarli lì. Ad esempio, per verificare il nome completo dell'utente è possibile avere un metodo per ottenere il valore booleano:

     public boolean hasDisplayedUserFullName (String userFullName) {
         return driver.findElement(By.xpath("xpathExpressionUsingFullName")).isDisplayed();
     }
    
  5. Se la tua pagina web è basata su iframe, preferisci avere anche le classi di pagine per iframe.

Vantaggi del modello di oggetto della pagina:

  1. Separazione pulita tra codice di prova e codice di pagina
  2. In caso di modifiche nell'interfaccia utente della pagina Web, non è necessario modificare il codice in più posizioni. Cambia solo nelle classi di pagine.
  3. Nessun localizzatore di elementi sparsi.
  4. Rende il codice più facile da capire
  5. Facile manutenzione

Introduzione (Utilizzo di Java)

Un esempio per eseguire il test di accesso basato sul modello di oggetto Pagina:

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 #

Gli oggetti Page devono contenere un comportamento, informazioni di ritorno per asserzioni e possibilmente un metodo per il metodo dello stato di pagina pronto all'inizializzazione. Il selenio supporta gli oggetti pagina usando le annotazioni. In C # è come segue:

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;
    }
}

gli appunti:

  • CacheLookup salva l'elemento nella cache e salva la restituzione di un nuovo elemento per ogni chiamata. Questo migliora le prestazioni ma non è buono per gli elementi che cambiano dinamicamente.
  • searchButton ha 2 nomi di classe e nessun ID, ecco perché non posso usare il nome della classe o l'id.
  • Ho verificato che i miei locator mi restituiranno l'elemento che desidero utilizzando gli Strumenti per sviluppatori (per Chrome), mentre in altri browser è possibile utilizzare FireBug o simili.
  • Search() metodo Search() restituisce un altro oggetto pagina ( ResultsPage ) mentre il clic di ricerca reindirizza a un'altra pagina.

Modello oggetto pagina Best Practices

  • Crea file separati per intestazione e piè di pagina (poiché sono comuni a tutte le pagine e non ha senso farne parte di una singola pagina)
  • Mantieni elementi comuni (come Cerca / Indietro / Avanti ecc.) In un file separato (l'idea è di rimuovere ogni tipo di duplicazione e mantenere la segregazione logica)
  • Per Driver, è una buona idea creare una classe Driver separata e mantenere il driver come statico in modo che sia possibile accedervi su tutte le pagine! (Ho tutte le mie pagine web estendono DriverClass)
  • Le funzioni utilizzate in PageObjects sono suddivise nel più piccolo chunk possibile tenendo presente la frequenza e il modo in cui verranno chiamate (il modo in cui hai fatto il login- anche se il login può essere scomposto in enterUsername e inserirePassword funzioni ma mantenerlo poiché la funzione di accesso è più logica perché nella maggior parte dei casi viene chiamata la funzione di login piuttosto che le chiamate separate per inserire usernameUn utente e immetterePassword funzioni)
  • L'utilizzo di PageObjects segrega lo script di test dagli elementLocators
  • Hanno funzioni di utilità nella cartella separata dei programmi di utilità (come DateUtil, excelUtils ecc.)
  • Avere configurazioni in una cartella conf separata (come l'impostazione dell'ambiente in cui i test devono essere eseguiti, la configurazione delle cartelle di output e di input)
  • Incorporare screenCapture in caso di errore
  • Avere una variabile di attesa statica nel DriverClass con un tempo di attesa implicito come si è fatto. Cerca sempre di avere attese condizionali piuttosto che attese statiche come: wait.until (ExpectedConditions). Ciò garantisce che l'attesa non rallenti l'esecuzione inutilmente.


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow