我刚开始使用webdriver的 ,而我努力学习的最佳实践,特别是使用PageObjects和PageFactory 。
这是我的理解是PageObjects应公开在网页上的各种操作,并隔离测试类的代码的webdriver。 很多时候,同样的操作会导致导航到取决于所使用的数据不同的页面。
例如,在这个假设的情况下登录,提供管理员凭据带你到AdminWelcome页面,并提供客户证书带你到CustomerWelcome页面。
因此,要实现这个最简单的方法就是公开两个方法,返回不同PageObjects ...
登录PageObject
package example;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class Login {
@FindBy(id = "username")
private WebElement username;
@FindBy(id = "password")
private WebElement password;
@FindBy(id = "submitButton")
private WebElement submitButton;
private WebDriver driver;
public Login(WebDriver driver){
this.driver = driver;
}
public AdminWelcome loginAsAdmin(String user, String pw){
username.sendKeys(user);
password.sendKeys(pw);
submitButton.click();
return PageFactory.initElements(driver, AdminWelcome.class);
}
public CustomerWelcome loginAsCustomer(String user, String pw){
username.sendKeys(user);
password.sendKeys(pw);
submitButton.click();
return PageFactory.initElements(driver, CustomerWelcome.class);
}
}
而在做测试类中的以下内容:
Login loginPage = PageFactory.initElements(driver, Login.class);
AdminWelcome adminWelcome = loginPage.loginAsAdmin("admin", "admin");
要么
Login loginPage = PageFactory.initElements(driver, Login.class);
CustomerWelcome customerWelcome = loginPage.loginAsCustomer("joe", "smith");
替代方法
而不是重复代码的,我希望有暴露一个更清洁的方式login()
其返回的相关PageObject方法。
我想到了创建的页面层次结构(或让他们实现一个接口),这样我可以使用它作为返回类型,但感觉笨拙。 我想出了以下内容:
public <T> T login(String user, String pw, Class<T> expectedPage){
username.sendKeys(user);
password.sendKeys(pw);
submitButton.click();
return PageFactory.initElements(driver, expectedPage);
}
这意味着你可以做测试类如下:
Login loginPage = PageFactory.initElements(driver, Login.class);
AdminWelcome adminWelcome =
loginPage.login("admin", "admin", AdminWelcome.class);
要么
Login loginPage = PageFactory.initElements(driver, Login.class);
CustomerWelcome customerWelcome =
loginPage.login("joe", "smith", CustomerWelcome.class);
这是灵活的-你可以添加一个ExpiredPassword网页,而不必改变login()
在所有的方法-添加另一测试,并通过在适当的过期证书和ExpiredPassword页面预期的页面。
当然,你可以很容易离开loginAsAdmin()
和loginAsCustomer()
方法,并以通用的调用替换它们的内容login()
这将随后进行私人)。 一个新的页面(如ExpiredPassword页),那么就需要另一种方法(如loginWithExpiredPassword()
这样做的好处是,方法名称实际上意味着什么(你可以很容易地看到,有登录的3个可能的结果),该PageObject的API是有点更容易使用(没有“的网页”来传递),但的webdriver代码仍然被重用。
进一步改进...
如果你没有露出单一login()
方法,你可以使它更明显的页面可以通过添加一个标记接口,这些网页登录即可到达(如果你暴露每个场景的方法这可能不是必要的)。
public interface LoginResult {}
public class AdminWelcome implements LoginResult {...}
public class CustomerWelcome implements LoginResult {...}
而更新的登录方法:
public <T extends LoginResult> T login(String user, String pw,
Class<T> expectedPage){
username.sendKeys(user);
password.sendKeys(pw);
submitButton.click();
return PageFactory.initElements(driver, expectedPage);
}
这两种方法似乎运作良好,但我不知道它是如何扩展为更复杂的情况。 我还没有看到任何代码示例喜欢它,所以我不知道其他人一样,当一个页面上的操作可能会导致取决于数据不同的结果呢?
或者是通常的做法是只复制webdriver的代码和揭露很多不同的方法进行数据/ PageObjects的每个排列?