到這節(jié)課為止我們已經(jīng)基本上把WebDriver和TestNG的基礎(chǔ)都講完了,下去開始講講實(shí)戰(zhàn)過程中我們會(huì)用到的一些思想和工具闹炉。
例如這節(jié)我們要講的PageObject思想蒿赢。相信如果現(xiàn)在你們的腳本已經(jīng)經(jīng)過幾個(gè)迭代的修改了,你們一定會(huì)遇到一個(gè)頭痛的問題渣触,那就是頁面變化诉植,以前腳本的定位方式不能用了,得修改定位方式昵观,那如果以往的腳本沒有用PageObject思想晾腔,意味著你得一個(gè)一個(gè)Case中把需要修改的定位方式找出來,然后再進(jìn)行修改啊犬。這不但照成腳本維護(hù)的成本加大灼擂,也可能照成大量代碼冗余。
那這時(shí)候PageObject就顯得尤為重要觉至。 那什么是PageObject呢剔应?
什么是PageObject思想
PageObject 見名思意,就是頁面對象语御。說白就是把頁面元素定位和頁面元素操作分開峻贮。
PageObject在實(shí)戰(zhàn)過程中我們回對腳本實(shí)現(xiàn)進(jìn)行分層。通常做法是分三層:
- 對象庫層
- 邏輯層
- 業(yè)務(wù)層
對象層用于存放我們的頁面元素和一些特殊控件操作应闯。邏輯層則是一些封裝好的功能用例模塊纤控。業(yè)務(wù)層則是我們真正的測試用例的操作。
當(dāng)然如果我們的測試數(shù)據(jù)量大時(shí)碉纺,我們還可以在三層基礎(chǔ)上再加一層 數(shù)據(jù)層船万,用于存放我們的測試數(shù)據(jù)刻撒,這也是比較常規(guī)的做法。
- 對象庫層
- 邏輯層
- 業(yè)務(wù)層
- 數(shù)據(jù)層
實(shí)戰(zhàn)例子
廢話不多說我們直接來看個(gè)例子耿导,我們還是以163郵箱登錄為例子声怔。
對象庫層
首先我們新建個(gè)叫LoginPage的類,編寫登錄頁面所有可能需要操作的元素定位方式和操作舱呻,代碼示例如下:
package com.selenium.pageobjcet;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
/**
* Created by 米陽 on 14/10/2017.
*/
public class LoginPage {
// 定位 ifrmae
public static By loginFrame = By.id("x-URS-iframe");
// 定位 郵箱地址輸入框
public static By emailField = By.name("email");
// 定位 密碼輸入框
public static By pwdFiled = By.name("password");
// 定位 登錄按鈕
public static By loginBtn = By.id("dologin");
WebDriver driver;
public LoginPage(WebDriver driver) {
this.driver = driver;
}
/**
* 往郵箱文本框輸入郵箱
* @param email 郵箱地址
*/
public void sendKeysEmail(String email) {
driver.findElement(emailField).clear();
driver.findElement(emailField).sendKeys(email);
}
/**
* 往密碼文本框輸入密碼
* @param pwd 密碼
*/
public void sendKeysPWD(String pwd) {
driver.findElement(pwdFiled).clear();
driver.findElement(pwdFiled).sendKeys(pwd);
}
}
這里我們只把郵件輸入框和密碼輸入框的操作進(jìn)行封裝醋火,當(dāng)然如果為了便于閱讀也可以把所有的元素操作進(jìn)行封裝取名。
操作層
我們再新建個(gè)叫LoginMail的類箱吕,用于登錄邏輯封裝胎撇,供業(yè)務(wù)層Case調(diào)用,實(shí)現(xiàn)如下:
package com.selenium.pageobjcet;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
/**
* Created by 米陽 on 14/10/2017.
*/
public class LoginMail {
WebDriver driver;
public LoginMail(WebDriver driver) {
this.driver = driver;
}
/**
* 登陸
*
* @param emial 郵箱地址
* @param pwd 密碼
*/
public void login(String emial, String pwd) {
LoginPage loginPage = new LoginPage(driver);
WebElement element = driver.findElement(LoginPage.loginFrame);
driver.switchTo().frame(element);
loginPage.sendKeysEmail(emial);
loginPage.sendKeysPWD(pwd);
driver.findElement(LoginPage.loginBtn).click();
}
}
業(yè)務(wù)層
最后我們來看下業(yè)務(wù)層的封裝殖氏,也就是我們真正Case的編寫:
package com.selenium.pageobjcet;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterClass;
import org.testng.annotations.BeforeClass;
import org.testng.annotations.Test;
import java.util.concurrent.TimeUnit;
/**
* Created by 米陽 on 14/10/2017.
*/
public class LoginTest {
WebDriver driver;
@BeforeClass
public void openChrome() {
System.setProperty("webdriver.chrome.driver", "./drivers/chromedriver.exe");
driver = new ChromeDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
}
@Test
public void testLogin2() {
driver.get("http://mail.163.com/");
LoginMail loginMail = new LoginMail(driver);
loginMail.login("meyoungtester", "meyoung123");
}
@AfterClass
public void closedChrome() {
driver.quit();
}
}
小結(jié)
經(jīng)過我們對登陸功能的改裝晚树,采用了PageObject思想后,假設(shè)以后要是登錄頁面的A元素變更雅采,我們就不需要在工程里面到處找用到這個(gè)A元素的Case去修改他們的定位方式爵憎,我們只需要打開我們的LoginPage,找到A元素的定位方式婚瓜,進(jìn)行修改宝鼓,則整個(gè)工程用到A元素定位的就自然而然的修改了。同樣如果哪天登錄流程變更了巴刻,例如登錄過程必須輸入驗(yàn)證碼愚铡,那么我們也不需要把所有Case涉及到登錄的都找出來,插入輸入驗(yàn)證碼過程胡陪,只需要在先在LoginPage里面登陸驗(yàn)證碼的定位方式沥寥,接著加入打開LoginMail,在登錄邏輯里面加入我們的驗(yàn)證碼輸入步驟柠座,則用到登錄邏輯的所有Case則不需要其他維護(hù)邑雅。
PageObject 的優(yōu)點(diǎn)
一張圖差不多對PO思想引入的前后對比。PO思想對界面交互細(xì)節(jié)進(jìn)行了封裝妈经,這樣可以使我們的自動(dòng)化測試腳本案例更關(guān)注業(yè)務(wù)淮野,而非界面細(xì)節(jié),提高了測試案例的可讀性吹泡。
PageFactory
PageFactory 整體思想同于PageObject思想骤星,只是表象顯示上不太一樣,它通過注解的方式來定位元素對象爆哑,例如:
對象庫層:
@FindBy(id = "kw")
public static WebElement emailName;
Case使用:
@Test
public void test(){
driver.get("https://www.baidu.com");
// 初始化 LoginPage
PageFactory.initElements(driver ,LoginPage.class);
LoginPage.emailName.sendKeys("Test");
}
PageObject VS PageFactor
WebDriver 提供了這兩種元素對象管理的思想洞难,總的來說沒有誰好誰壞,看個(gè)人習(xí)慣泪漂,實(shí)際工程也可以兩者結(jié)合使用廊营。就個(gè)人而言更習(xí)慣PageObject思想,但PageFactor也不錯(cuò)萝勤,通過注解方式代碼看起來更加簡潔露筒。