【问题标题】:Need of page factory in page object model页面对象模型中需要页面工厂
【发布时间】:2014-11-18 16:11:13
【问题描述】:

谁能解释一下页面对象模型中pagefactory的需要是什么。

例如。我们使用下面的代码来初始化页面对象类。

LoginPage loginPage = PageFactory.initElements(driver, LoginPage.class);

为什么我们不能使用

LoginPage loginPage = new LoginPage(driver);

同样在我们使用的每个页面对象方法中返回新页面时

return new PageFactory.initElements(driver, HomePage.class);

为什么不应该

return new HomePage(driver);

请帮助我理解 PageFactory,因为我是页面对象模式的新手。我认为我们仍然可以在不使用 PageFactory 的情况下进行管理。

【问题讨论】:

  • 您可以在不使用 PageFactory 的情况下进行管理。阅读设计模式。

标签: java design-patterns selenium selenium-webdriver pageobjects


【解决方案1】:

事实上,您可以在不使用PageFactory 类的情况下使用页面对象模式。页面对象模式只是将您的业务逻辑从页面的物理结构中抽象出来。 PageFactory 类为您提供的功能是使用注释自动查找页面上的元素,而无需使用显式的 findElement 调用。它可以让你编写这样的代码:

public class LoginPage {
  @FindBy(how = How.ID, using = "user")
  private WebElement userNameTextBox;

  @FindBy(how = How.ID, using = "password")
  private WebElement passwordTextBox;

  public void fillLoginDetails(String userName, String password) {
    userNameTextBox.sendKeys(userName);
    passwordTextBox.sendKeys(password);
  }
}

注意这里没有明确的findElement 调用。使用PageFactory 可以让您更清晰地编写此代码并消除一些样板代码。同样的事情可以通过在页面对象中使用findElement 来定位适当的元素来完成。这是一种风格选择。

【讨论】:

  • 感谢您的评论。因此,由于我们在使用页面工厂时没有在 LoginPage 或任何页面对象中使用驱动程序实例,我们在哪里编写自定义等待等(或任何涉及驱动程序对象的操作)?这些等待应该是页面对象的一部分还是我的测试的一部分?
【解决方案2】:

PageFactory 使用您提供的 WebDriver 注入在您的页面对象中定义的 WebElements。

PageFactory 的文档说:

PageFactory 依赖于使用合理的默认值:Java 类中的字段名称被假定为 HTML 页面上元素的“id”或“name”。

因此,您只需使用 WebElement 的 id 或名称定义 WebElement 类型的字段,PageFactory 会注意它是否可用。

我认为我们仍然可以在不使用 PageFactory 的情况下进行管理。

是的,你可以。如果您不使用PageFactory,则必须使用WebDriver api 查找WebElements,例如

WebElement searchBox = driver.findElement(By.id("q"));

但您也可以使用 @FindBy@FindBys@FindAll 注释字段,例如

@FindBy(how = How.ID, using = "q")
private WebElement searchBox;

我是页面对象模式的新手

页面对象是一些网页的封装。它的 api 提供了对网页的类似用户的访问,并隐藏了页面的实现细节(网页元素、id 等)。因此,您可以按照用户描述测试的方式编写测试。

例如

 @Test
 public void googleSearch(){
     WebDriver driver = ....;

     GooglePage google = GooglePage.open(driver);
     SearchResultPage searchResult = google.search("stackoverflow");
     SearchResult firstResult = searchResult.getResult(0); // first result

     Assert.assertEquals("Stack Overflow", firstResult.getTitle());
     ...
 }

【讨论】:

  • 感谢您的评论。因此,由于我们在使用页面工厂时没有在 LoginPage 或任何页面对象中使用驱动程序实例,我们在哪里编写自定义等待等(或任何涉及驱动程序对象的操作)?这些等待应该是页面对象的一部分还是我的测试的一部分?
  • 我认为等待应该是页面对象的一部分。例如。如果页面包含一个组件,其内容是由 ajax 调用加载的,那么您的测试应该在加载之前获得对它的引用。例如。 TableComponent tc = page.getResultTable()。这也意味着您需要页面和组件中的 Web 驱动程序。通常我使用LoadableCompoent在页面上实现页面和组件:code.google.com/p/selenium/wiki/LoadableComponent
  • 感谢 Rene 的宝贵反馈
【解决方案3】:

我看到您使用 java 处理 selenium。你应该看看 Arquillian-Graphene 框架。这是一个扩展。因此它不会与您现有的框架混淆。

使用 Arquillian 框架的主要目的是 - 你不需要 Page Factory。它有一组很好的注释可以在运行时注入页面对象模型。

例如:我为 Google 创建了一个页面对象,如下所示。

public class Google {

    @Drone
    private WebDriver driver;

    public void goTo(){
        driver.get("https://www.google.com");
    }

    public boolean isAt(){
        return driver.getTitle().equals("Google");
    }
}

在我的 testng/junit 中,

@RunAsClient
public class GoogleSearchTest extends Arquillian{

    @Page
    Google google;


    @Test(priority = 1)
    public void launchGoogle(){

        google.goTo();
        Assert.assertTrue(google.isAt());

    }

}

你注意到了吗? @Drone - 自动注入浏览器实例。 @Page 自动创建一个 Google 页面对象实例。

点击此处了解更多信息:

http://www.testautomationguru.com/arquillian-graphene-page-fragments/

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多