前期已經做好使用Jenkins做buildhttp://www.cnblogs.com/tobecrazy/p/4529399.html
做自動化框架,不可避免的就是物件庫。
有一個好的物件庫,可以讓整個測試體系:
- 更容易維護
- 大大增加程式碼重用
- 增加測試系統的穩定性
這裡先了解一下我所說的物件庫:
所謂的頁面物件,是指每一個真是的頁面是一個物件。
比如zhihu的登陸頁面是一個頁面物件,http://www.zhihu.com/#signin
這個頁面物件主要包含一個輸入郵箱的輸入框(一個元素物件),一個輸入密碼的密碼框
一個登陸框。當然,zhihu不止一個頁面,有無數頁面,每一個頁面都可以封裝為一個物件。而每個
頁面的元素,也可以封裝成一個個元素物件。
為什麼要封裝成一個個物件?
還是以這個登陸頁面為例,如果有一天zhihu改版,登陸介面UI變了,(但是需要輸入使用者名稱和密碼還有登陸按鈕不會消失吧)。
登陸頁面的元素的位置也相應改變,如果你的測試用例沒有封裝過頁面和元素, 每個頁面都是拿webdriver 直接寫,頁面元素定位
也分佈到測試用例中,這要維護起來要全部改掉測試用例。如果你封裝了頁面,封裝了元素,再封裝一個對應的登陸Action,你的每個
測試用例是呼叫的login.action()。 這樣,你只需要改變你物件庫的內容就完美解決UI變化,而不必一個個修改測試用例。
測試框架目錄如下:
接下來一這個登陸為例:
首先封裝一個BasePage的類,畢竟所有的頁面都有共同的東西,每個頁面都有元素,每個頁面元素都有相應的方法
這裡簡單封裝了幾個方法,如type
package com.dbyl.libarary.utils; import java.io.IOException; import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.interactions.Actions; import org.openqa.selenium.support.ui.ExpectedCondition; import org.openqa.selenium.support.ui.WebDriverWait; public class BasePage { protected WebDriver driver; protected String[][] locatorMap; protected BasePage(WebDriver driver) throws IOException { this.driver = driver; locatorMap = ReadExcelUtil.getLocatorMap(); } protected void type(Locator locator, String values) throws Exception { WebElement e = findElement(driver, locator); e.sendKeys(values); } protected void click(Locator locator) throws Exception { WebElement e = findElement(driver, locator); e.click(); } protected void clickAndHold(Locator locator) throws IOException { WebElement e = findElement(driver, locator); Actions actions = new Actions(driver); actions.clickAndHold(e).perform(); } public WebDriver getDriver() { return driver; } public void setDriver(WebDriver driver) { this.driver = driver; } public WebElement getElement(Locator locator) throws IOException { return getElement(this.getDriver(), locator); } /** * get by parameter * * @author Young * @param driver * @param locator * @return * @throws IOException */ public WebElement getElement(WebDriver driver, Locator locator) throws IOException { locator = getLocator(locator.getElement()); WebElement e; switch (locator.getBy()) { case xpath: e = driver.findElement(By.xpath(locator.getElement())); break; case id: e = driver.findElement(By.id(locator.getElement())); break; case name: e = driver.findElement(By.name(locator.getElement())); break; case cssSelector: e = driver.findElement(By.cssSelector(locator.getElement())); break; case className: e = driver.findElement(By.className(locator.getElement())); break; case tagName: e = driver.findElement(By.tagName(locator.getElement())); break; case linkText: e = driver.findElement(By.linkText(locator.getElement())); break; case partialLinkText: e = driver.findElement(By.partialLinkText(locator.getElement())); break; default: e = driver.findElement(By.id(locator.getElement())); } return e; } public boolean isElementPresent(WebDriver driver, Locator myLocator, int timeOut) throws IOException { final Locator locator = getLocator(myLocator.getElement()); boolean isPresent = false; WebDriverWait wait = new WebDriverWait(driver, 60); isPresent = wait.until(new ExpectedCondition<WebElement>() { @Override public WebElement apply(WebDriver d) { return findElement(d, locator); } }).isDisplayed(); return isPresent; } /** * This Method for check isPresent Locator * * @param locator * @param timeOut * @return * @throws IOException */ public boolean isElementPresent(Locator locator, int timeOut) throws IOException { return isElementPresent(driver,locator, timeOut); } /** * * @param driver * @param locator * @return */ public WebElement findElement(WebDriver driver, final Locator locator) { WebElement element = (new WebDriverWait(driver, locator.getWaitSec())) .until(new ExpectedCondition<WebElement>() { @Override public WebElement apply(WebDriver driver) { try { return getElement(driver, locator); } catch (IOException e) { // TODO Auto-generated catch block return null; } } }); return element; } public Locator getLocator(String locatorName) throws IOException { Locator locator; for (int i = 0; i < locatorMap.length; i++) { if (locatorMap[i][0].endsWith(locatorName)) { return locator = new Locator(locatorMap[i][1]); } } return locator = new Locator(locatorName); } }
接下來封裝元素,Webdriver的元素,每個元素都有相應的定位地址(xpath路徑或css或id)等待時間和定位型別,預設為By.xpath
package com.dbyl.libarary.utils; /** * This is for element library * * @author Young * */ public class Locator { private String element; private int waitSec; /** * create a enum variable for By * * @author Young * */ public enum ByType { xpath, id, linkText, name, className, cssSelector, partialLinkText, tagName } private ByType byType; public Locator() { } /** * defaut Locator ,use Xpath * * @author Young * @param element */ public Locator(String element) { this.element = element; this.waitSec = 3; this.byType = ByType.xpath; } public Locator(String element, int waitSec) { this.waitSec = waitSec; this.element = element; this.byType = ByType.xpath; } public Locator(String element, int waitSec, ByType byType) { this.waitSec = waitSec; this.element = element; this.byType = byType; } public String getElement() { return element; } public int getWaitSec() { return waitSec; } public ByType getBy() { return byType; } public void setBy(ByType byType) { this.byType = byType; } }
接下來就是登陸頁面的類,這個登陸頁面的元素,放在excel統一管理,要獲取元素的資訊,首先從excel讀取。
讀取excel的頁面元素是使用POI開源框架
package com.dbyl.libarary.utils; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; public class ReadExcelUtil { static String path; /** * @author Young * @return * @throws IOException */ public static String[][] getLocatorMap() throws IOException { path = "C:/Users/Young/workspace/Demo/src/com/dbyl/libarary/pageAction/UILibrary.xls"; File f1 = new File(path); FileInputStream in = new FileInputStream(f1); HSSFWorkbook wb = new HSSFWorkbook(new POIFSFileSystem(in)); Sheet sheet = wb.getSheetAt(0); Row header = sheet.getRow(0); String[][] locatorMap = new String[sheet.getLastRowNum() + 1][header .getLastCellNum()]; for (int rownum = 0; rownum <= sheet.getLastRowNum(); rownum++) { // for (Cell cell : row) Row row = sheet.getRow(rownum); if (row == null) { continue; } String value; for (int cellnum = 0; cellnum <= row.getLastCellNum(); cellnum++) { Cell cell = row.getCell(cellnum); if (cell == null) { continue; } else { value = ""; } switch (cell.getCellType()) { case Cell.CELL_TYPE_STRING: value = cell.getRichStringCellValue().getString(); break; case Cell.CELL_TYPE_NUMERIC: if (DateUtil.isCellDateFormatted(cell)) { value = cell.getDateCellValue().toString(); } else { value = Double.toString((int) cell .getNumericCellValue()); } break; case Cell.CELL_TYPE_BOOLEAN: value = Boolean.toString(cell.getBooleanCellValue()); break; case Cell.CELL_TYPE_FORMULA: value = cell.getCellFormula().toLowerCase(); break; default: value = " "; System.out.println(); } locatorMap[rownum][cellnum] = value; } } in.close(); wb.close(); return locatorMap; } }
頁面類
package com.dbyl.libarary.pageAction; import java.io.IOException; import java.util.concurrent.TimeUnit; import org.openqa.selenium.WebDriver; import com.dbyl.libarary.utils.BasePage; import com.dbyl.libarary.utils.Locator; public class LoginPage extends BasePage { WebDriver driver; public WebDriver getDriver() { return driver; } public LoginPage(WebDriver driver) throws IOException { super(driver); driver.get("http://www.zhihu.com/#signin"); } Locator loginEmailInputBox = new Locator("loginEmailInputBox"); Locator loginPasswordInputBox = new Locator("loginPasswordInputBox"); Locator loginButton = new Locator("loginButton"); Locator profile = new Locator( "profile"); public void typeEmailInputBox(String email) throws Exception { type(loginEmailInputBox, email); } public void typePasswordInputBox(String password) throws Exception { type(loginPasswordInputBox, password); } public void clickOnLoginButton() throws Exception { click(loginButton); } public boolean isPrestentProfile() throws IOException { return isElementPresent(profile, 20); } public void waitForPageLoad() { super.getDriver().manage().timeouts() .pageLoadTimeout(30, TimeUnit.SECONDS); } }
接下來就是登陸的Action
package com.dbyl.libarary.action; import org.openqa.selenium.WebDriver; import org.testng.Assert; import com.dbyl.libarary.pageAction.HomePage; import com.dbyl.libarary.pageAction.LoginPage; public class CommonLogin { private static WebDriver driver; public static WebDriver getDriver() { return driver; } static LoginPage loginPage; public static HomePage login(String email, String password) throws Exception { loginPage = new LoginPage(getDriver()); loginPage.waitForPageLoad(); loginPage.typeEmailInputBox(email); loginPage.typePasswordInputBox(password); loginPage.clickOnLoginButton(); Assert.assertTrue(loginPage.isPrestentProfile(), "login failed"); return new HomePage(getDriver()); } public static HomePage login() throws Exception { return CommonLogin.login("seleniumcookies@126.com", "cookies123"); } public static void setDriver(WebDriver driver) { CommonLogin.driver = driver; } }
至此為止,已經封裝完畢
接下來就能在測試用例直接呼叫者
package com.dbyl.tests; import org.openqa.selenium.WebDriver; import org.testng.annotations.AfterMethod; import org.testng.annotations.BeforeMethod; import org.testng.annotations.Test; import com.dbyl.libarary.action.ViewHomePage; import com.dbyl.libarary.utils.DriverFactory; import com.dbyl.libarary.utils.UITest; public class loginTest extends UITest{ WebDriver driver=DriverFactory.getChromeDriver(); @BeforeMethod(alwaysRun=true) public void init() { super.init(driver); ViewHomePage.setDriver(driver); //CommonLogin.setDriver(driver); } @Test(groups="loginTest") public void loginByUerName() throws Exception { //CommonLogin.login("seleniumcookies@126.com","cookies123"); ViewHomePage.viewMyProfile(); } @AfterMethod(alwaysRun=true) public void stop() { super.stop(); } }
demo的下載地址:https://github.com/tobecrazy/Demo