当前位置: 首页 > 知识库问答 >
问题:

页面对象模型。组合与封装

简意
2023-03-14

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

  1. 为每个元素和每个交互定义一个方法。例如,我有一个元素“Submit”。在我的page类中,我将创建ClickSubmit()公共方法,并在测试中调用它。提交将包含驱动程序。FindElement(提交者)。点击();如果我在页面上有很多元素,我会有同样多的方法,基本上重复相同的函数
  2. 定义一个单击方法,该方法接受web元素定位器作为参数,并使用复杂的switch语句确定应该单击哪个元素

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

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

无论哪种方式,交互方法只定义一次,测试编写者不需要知道如何单击元素或与元素交互,只需简单地说elementLocator即可。单击()(如果作为扩展实现)或单击元素(elementLocator)。

我试图完全避免编写测试,比如:Driver。FindElement(元素定位器)。单击()。

我想知道社区的意见,也许我完全在监督一些显而易见的事情。

共有1个答案

赵骏奇
2023-03-14

您不需要自动化所有页面或捕获所有对象。您需要做的是捕获测试所需的一切<代码>页面对象模型旨在最小化测试框架中的“更改”因素,并通过这样做最小化将来应用任何更改所需的工作量。

如果您使用PageFactory,您不需要为每个webelements编写driver.findElement(By.(...))。单击()。相反,您的代码可以看起来像这样:

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类中创建一个方法,它正好可以做到这一点。然后,基类的构造函数将调用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();
    }
}

等待只是一个例子来解释一般的想法。

编辑

由于不应该使用PageFactory,根据评论和这个答案:为什么页面工厂应该避免我已经编辑了我的答案。我把两个例子留在这里,并决定他想如何进入OP。

不管怎样,你最终想要实现的是方法链接。通过这种方式,您的测试是可读的,可以成为“一个测试一个断言”的一个很好的例子,并且看起来像这样:

assertEquals("Title does not match.",
    expectedTitle, new LoginPage(driver)
        .openLoginPage()
        .login(user)
        .openSomePage()
        .clickButton()
        .getTitle());
 类似资料:
  • 我正在使用Selenium为我的网站构建一个测试框架,我实际上希望您在使用页面对象模型时对良好实践的想法:让我们说,我有一个欢迎页面,其中包含一个注销按钮存在的标题,这个标题可以在大多数页面中看到在我的页面中,我认为最好为标题写一个单独的类,比如: 公共类欢迎页 我的问题是,你认为在欢迎页面中包含标题作为属性更好还是应该将它们分开? 让我们以注销测试方法的代码为例: 案例一: 案例2: 第二个问题

  • 是否有任何Gem(比如siteprism:用于Web自动化测试)可以在我的移动自动化测试项目中使用,以使用页面对象模型模式定义屏幕。 提前谢谢

  • 我正在使用Perl和Selenium构建一个测试自动化项目。我正在使用页面对象模型。我有点不确定Selenium驱动程序将适合页面对象模型的实现。 每个页面对象是否应该“有”一个驱动程序?我的想法是,每个页面对象代表页面向用户提供的一组服务。考虑到这个概念,页面对象与驱动程序没有“has-a”关系。页面对象与驱动程序交互。不过,我仍在寻求建议。我应该将驱动程序作为web应用程序中每个页面对象的一部

  • 想象有一个页面在说http://google.com/AddUser在这里输入记录的详细信息,然后单击保存。完成此操作后,页面将重定向到 http://google.com/userList 您可以在其中查看用户列表,包括您刚刚输入的新记录。 如果我们按照页面对象模型,那么在和验证记录是否实际保存和显示的方法应该在 如果我们认为addUser和userList是两个类的对应对象,它会像下面这样:

  • 我想在我的页面对象中使用剧作家的定位器。我找到了一个Javascript示例(为了简洁起见,将其剥离): 试图在我的Java代码中做同样的事情: 引发空指针异常,因为初始化登录按钮时,尚未启动。 我可以 但是对于大型页面对象类来说,这将变得有点冗长/混乱。 有没有关于如何在Java中实现这一点的想法? 谢谢

  • 在Java页面对象模型中创建步骤时实例化对象的最佳方法是什么? 有人知道Cucumber脚本是如何编译的吗? 我想,如果一切都建成并符合要求,下面的第二个或第三个选项可能是最好的方法。 如果只编译与正在执行的测试相关的步骤,那么我想这将是第一个。 我举了以下例子: 以上所有步骤(在同一个LoginSteps.java类中加上更多)从以下开始 这是最好的方法,还是创建单个实例更好? 或者在Login