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作為屬性。
Page Object Model