页面对象模型。成分与封装

时间:2019-05-16 05:17:30

标签: selenium automation webdriver pom.xml qa

我们有一个复杂的多页面应用程序,在一个页面上有多达100个Web元素,多个网格,动态元素等。 POM模式指示有关页面的所有内容都封装在页面中,即 在页面类中,我需要将定位符定义为字符串或Bys。我还应该定义公共方法来与这些元素进行交互。 有两种处理这些交互的方法:

  1. 为每个元素和每个交互定义一个方法。例如,我有一个元素“ Submit”。在页面类中,我将创建ClickSubmit()公共方法,并在测试中将其调用。 提交将包含Driver.FindElement(submitLocator).Click(); 如果页面上有很多元素,那么我将有很多方法,实质上是重复相同的功能。
  2. 定义将Web元素定位器作为参数的单击方法,并使用复杂的switch语句确定应单击的元素。

这两种方法都适用于元素数量有限的较小页面。

还有第三种方法,可以在BasePage的帮助器类中定义通用的click方法(所有页面都继承自BasePage)或定义扩展方法,这些方法将直接作用于element。辅助方法可以增加内置等待的好处。

无论哪种方式,交互方法将仅定义一次,并且测试的编写者将不需要通过简单地说出elementLocator.Click()(如果实现为扩展)或ClickElement来知道如何单击或与元素交互。 (elementLocator)。

我试图完全避免编写如下测试: Driver.FindElement(elementLocator).Click()。

我想了解社区的意见,也许我正在完全监督一些明显的事情。

1 个答案:

答案 0 :(得分:1)

您不需要自动化所有页面或捕获所有对象。您需要做的是捕获测试所需的一切。 Page Object模型旨在最大程度地减少测试框架中的“变更”因素,并通过这种方式最大程度地减少将来应用任何变更所需的工作量。

如果您使用PageFactory,则无需为每个网络元素都写一个driver.findElement(By.(...)).click()。相反,您的代码应如下所示:

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

这样,您就不需要带有一些super方法的click类。当然,如果默认的click行为适合您,那就可以了。如果要引入一些waitActions等,可以随时在超类中创建一个方法,这将完全做到这一点。然后,基类的构造函数将调用super(driver),而超类将必须执行PageFactory.initElements(driver, this)方法。因此,您的代码需要这样的内容:

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

等待只是说明总体思路的一个例子。

编辑

根据注释和以下答案,由于不应该使用PageFactoryWhy Page Factory should be avoided我已经编辑了答案。 我将在此处留下两个示例,并决定他要如何进行OP。

一种或另一种方法,最后要实现的目标是method chaining。这样,您的测试就变得可读,可以成为“一个测试一个断言”的好例子,并且看起来像这样:

assertEquals("Title does not match.",
    expectedTitle, new LoginPage(driver)
        .openLoginPage()
        .login(user)
        .openSomePage()
        .clickButton()
        .getTitle());