Page Modèle D'Objet. Composition vs Encapsulation


Nous avons une application multi-pages complexe, avec jusqu'à 100 éléments web sur une seule page, plusieurs grilles, éléments dynamiques, etc. Le modèle POM dicte que tout ce qui concerne une page est encapsulé dans la page, c'est-à-dire dans la classe page, je dois définir mes localisateurs sous forme de chaînes ou de Bys. Je devrais également définir des méthodes publiques pour interagir avec ces éléments. Il existe 2 façons de gérer ces interactions:

  1. Définir une méthode pour chaque élément et chaque interaction. Par exemple, j'ai un élément "Soumettre". Dans ma classe de page, je créerais la méthode publique ClickSubmit () et dans mon test, je l'invoquerais. Soumettre contiendrait le pilote.FindElement (submitLocator).Cliquer(); Si j'ai beaucoup d'éléments sur la page, j'aurais autant de méthodes, répétant essentiellement la même fonction.
  2. Définir une méthode en un seul clic qui accepte un localisateur d'élément Web en tant que paramètre et en utilisant une instruction switch complexe, détermine quel élément il doit cliquer.

Les deux méthodes fonctionnent pour les pages plus petites avec un nombre limité d'éléments.

Il existe cependant une troisième façon, de définir une méthode de clic générique dans une classe d'aide à la page de base (toutes les pages héritent de la page de base) ou de définir des méthodes d'extension, qui agiront directement sur l'élément. Les méthodes d'assistance peuvent avoir un avantage supplémentaire d'attente intégré.

De toute façon, les méthodes d'interaction ne seront définies qu'une seule fois et un compositeur de tests n'aura pas besoin de savoir comment cliquez ou interagissez avec un élément, en disant simplement elementLocator.Click () (s'il est implémenté en tant qu'extension) ou ClickElement (elementLocator).

J'essaie d'éviter complètement d'avoir à écrire des tests tels que: Pilote.FindElement (elementLocator).Cliquer().

Je voulais connaître les opinions de la communauté et peut-être que je supervise complètement quelque chose d'évident.

Author: Sparkle, 2019-05-16

1 answers

Vous n'avez pas besoin d'automatiser toutes les pages, ou de capturer tous les objets. Ce que vous devez faire est de capturer tout ce qui est requis par vos tests. Page Object le modèle est conçu pour minimiser le facteur "changement" dans votre cadre de test et, ce faisant, minimiser la quantité de travail qui sera nécessaire pour appliquer des changements à l'avenir.

Si vous utilisez PageFactory vous n'avez pas besoin d'écrire un driver.findElement(By.(...)).click() pour chacune des webelements. Au lieu de cela, votre code peut ressembler à ceci:

public class SomePage {
    @FindBy(id = "some_id");
    private WebElement button;

    private WebDriver driver;

    public SomePage(WebDriver driver) {
        this.driver = driver;
    }

    public SomePage clickButton() {
        button.click();
        return this;
    }

    public String getTitle() {
        return driver.getTitle();
    }
}

De cette façon, vous ne besoin d'une classe super avec une méthode click de fantaisie. C'est bien sûr si le comportement par défaut click vous convient. Si vous voulez présenter certains wait, Actions et ainsi de suite, n'hésitez pas à créer une méthode en super classe, qui fera exactement cela. Le constructeur de la classe de base appellerait alors super(driver) et la super classe devrait exécuter la méthode PageFactory.initElements(driver, this). Donc, votre code aimerait quelque chose comme ceci:

public class BasePage {
    private WebDriver driver;

    protected BasePage(WebDriver driver) {
        this.driver = driver;
    }

    protected void superClick(By elementLocator) {
        WebDriverWait wait = new WebDriverWait(driver, 10);
        wdWait.until(ExpectedConditions
            .presenceOfElementLocated(By.cssSelector("selector"))).click();
    }
}

public class SomePage extends BasePage{

    private static final By button = By.cssSelector("some_selector");

    private WebDriver driver;

    public SomePage(WebDriver driver) {
        super(driver);
        this.driver = driver;
    }

    public SomePage clickButton() {
        superClick(button);
        return this;
    }

    public String getTitle() {
        return driver.getTitle();
    }
}

, L'attente est juste un exemple pour expliquer le général idée.

MODIFIER

Puisque le PageFactory ne devrait pas être utilisé, selon les commentaires et cette réponse: Pourquoi la Page Factory devrait être évitée J'ai modifié ma réponse. Je laisse les deux exemples ici et la décision comment il veut procéder à OP.

D'une manière ou d'une autre, ce que vous voulez réaliser à la fin est method chaining. De cette façon, votre test est lisible, peut être un bon exemple de "one test one assertion" et ressemblera à ceci:

assertEquals("Title does not match.",
    expectedTitle, new LoginPage(driver)
        .openLoginPage()
        .login(user)
        .openSomePage()
        .clickButton()
        .getTitle());
 1
Author: Moro, 2019-05-16 16:47:47