Page Object Model
Page Object Model Framework which is also known as Page Object Design Pattern or Page Objects
PO模式的最大优势是如果UI或者任何页面的HTML对象有了变化,测试并不需要任何改动。只有页面对象的代码受到了影响,却对测试代码无任何影响。
Why?
想象一下当我们要处理100多个测试,包含了很多的stepDefinitions文件时项目中的代码行数会有多少?整个项目的代码将变得难以管理和维护。为了更好的管理代码,提高可用性,这个模式建议将应用程序划分成不同的页面或者将一个单独页面划分成多个子页面。我们没有任何结构的代码,只需要关注在元素和向Selenium driver发送命令上。
然后,PO模型技术提供了与多个网页工作的解决方案,阻止了不想要的代码重复,让代码维护变成了不复杂的事。总的来说,程序中的每个页面就是自己的一个唯一的类,页面元素在每个类中实现。
How to implement PO Model?
有两种方式实现POM:
1. Regular Jave classes. 这个不推荐,因为Selenium已经提供了更好的解决方案,也就是Selenium PageFactory
2. Selenium PageFactory。页面工厂是Selenium Webdriver内置的页面对象模型,很完善。
页面工厂使用页面类的初始化元素Initialize Elements,而不是使用FindElement or FindElements. 注解用来给目标对象提供描述性的名字,进而提高了代码阅读性
PageFactory是为了支持页面设计模式而开发出来的,它的方法在selenium.support库里面。
PageFactory提供初始化页面元素的方法,如果页面存在大量的AJAX的技术,只要页面更新一次,它就好重新查找一次元素,所以不会出现StaleElementExecption这个error,
如果你不想它每次更新,你可以加上@CacheLookup
页面设计模式,可以提供你一个接口,然后你在这个接口上面,构建你自己项目中的页面对象,使用PageFactory使得测试更简单,更少的代码编写。
如果@FindBy没有指定,它会默认的查找id属性,然后是name属性,如果还没有找到就会报错。如果这个元素存在,我们不用担心它,PageFactory会初始化这个元素,不会报任何错误。
案例:
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.CacheLookup;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;
public class BaiduSearchPage {
WebDriver driver;
@FindBy(id = "kw")
@CacheLookup
WebElement searchField;
@FindBy(id = "su")
@CacheLookup
WebElement searchButton;
public BaiduSearchPage(WebDriver driver){
this.driver = driver;
PageFactory.initElements(driver,this);
}
public void inputText(String search){
searchField.sendKeys(search);
}
public void clickButton(){
searchButton.click();
}
}
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.firefox.FirefoxDriver;
public class Test {
public static void main(String[] args) {
BaiduSearchPage searchPage;
WebDriver driver =new FirefoxDriver();
driver.manage().window().maximize();
driver.get("http://www.baidu.com");
searchPage =new BaiduSearchPage(driver);
searchPage.inputText("selenium");
searchPage.clickButton();
}
}
@FindBy可以接收TagName,PartialLinkText, Name,LinkText,Id,Css,ClassName,Xpath作为属性。