之前已经写过一篇:

selenium测试框架篇,页面对象和元素对象的管理

上次使用的excel作为Locator对象管理,由于excel处理不够方便,有以下缺点:

  • 不能实现分page 加载Locator对象
  • 不能够实现Locator对象重名
  • 文件比较大,读写速度没有xml快

所以,重新写了使用dom4j操作xml,使用xml管理Locator对象,能够有效解决以上问题

首先,定义Locator文件

<?xml version="1.0" encoding="UTF-8"?>

<map>
<!--locator of page map info -->
<page pageName="com.dbyl.libarary.pageAction.HomePage">
<!--Locator lists -->
<locator type="ByXpath" timeOut="3" value="//div[@class='top-nav-profile']//img[@class='avatar']">profile</locator>
</page>
<!--locator of page map info -->
<page pageName="com.dbyl.libarary.pageAction.LoginPage">
<!--Locator lists -->
<locator type="" timeOut="3" value="//input[@name='account' and not(@autocomplete)]">loginEmailInputBox</locator>
<locator type="ByXpath" timeOut="3" value="//button[@class='sign-button submit' and text()='登录']">loginButton</locator>
<locator type="ByXpath" timeOut="3" value="//div[@class='top-nav-profile']//img[@class='avatar']">profile</locator>
<locator type="ByXpath" timeOut="3" value="//input[@name='password' and @placeholder='密码']">loginPasswordInputBox</locator>
</page>
</map>

每一个Page对应一个真实的页面,而每一个page下的Locator对应一个真实的页面element

之前定义过的Locator类如下:

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;
} }

每一个Locator对象包含3属性 ByType 、timeOut时间和相应的xpath、id......的value

接下来需要写一个wrapper

package com.dbyl.libarary.utils;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator; import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter; import com.dbyl.libarary.utils.Locator.ByType; public class xmlUtils { /**
* @author Young
* @param path
* @param pageName
* @return
* @throws Exception
*/
public static HashMap<String, Locator> readXMLDocument(String path,
String pageName) throws Exception {
System.out.print(pageName);
HashMap<String, Locator> locatorMap = new HashMap<String, Locator>();
locatorMap.clear();
File file = new File(path);
if (!file.exists()) {
throw new IOException("Can't find " + path);
}
SAXReader reader = new SAXReader();
Document document = reader.read(file);
Element root = document.getRootElement();
for (Iterator<?> i = root.elementIterator(); i.hasNext();) {
Element page = (Element) i.next();
if (page.attribute(0).getValue().equalsIgnoreCase(pageName)) {
System.out.println("page Info is:" + pageName);
for (Iterator<?> l = page.elementIterator(); l.hasNext();) {
String type = null;
String timeOut = "3";
String value = null;
String locatorName = null;
Element locator = (Element) l.next();
for (Iterator<?> j = locator.attributeIterator(); j
.hasNext();) {
Attribute attribute = (Attribute) j.next();
if (attribute.getName().equals("type")) {
type = attribute.getValue();
System.out.println(">>>>type " + type);
} else if (attribute.getName().equals("timeOut")) {
timeOut = attribute.getValue();
System.out.println(">>>>timeOut " + timeOut);
} else {
value = attribute.getValue();
System.out.println(">>>>value " + value);
} }
Locator temp = new Locator(value,
Integer.parseInt(timeOut), getByType(type));
locatorName = locator.getText();
System.out.println("locator Name is " + locatorName);
locatorMap.put(locatorName, temp);
}
continue;
} }
return locatorMap; } /**
* @param type
*/
public static ByType getByType(String type) {
ByType byType = ByType.xpath;
if (type == null || type.equalsIgnoreCase("xpath")) {
byType = ByType.xpath;
} else if (type.equalsIgnoreCase("id")) {
byType = ByType.id;
} else if (type.equalsIgnoreCase("linkText")) {
byType = ByType.linkText;
} else if (type.equalsIgnoreCase("name")) {
byType = ByType.name;
} else if (type.equalsIgnoreCase("className")) {
byType = ByType.className;
} else if (type.equalsIgnoreCase("cssSelector")) {
byType = ByType.cssSelector;
} else if (type.equalsIgnoreCase("partialLinkText")) {
byType = ByType.partialLinkText;
} else if (type.equalsIgnoreCase("tagName")) {
byType = ByType.tagName;
}
return byType;
} /**
* @author Young
* @throws IOException
*/
public static void writeXMLDocument() throws IOException {
OutputFormat format = OutputFormat.createPrettyPrint();
XMLWriter writer = new XMLWriter(new FileWriter("output.xml"), format);
Document document = DocumentHelper.createDocument();
Element root = document.addElement("map");
root.addComment("locator of page map info");
Element page = root.addElement("page").addAttribute("pageName",
"com.dbyl.libarary.pageAction.HomePage");
page.addComment("Locator lists");
page.addElement("locator").addAttribute("type", "ByName")
.addAttribute("timeOut", "3")
.addAttribute("value", "\\\\div[@name]").addText("loginButton");
page.addElement("locator").addAttribute("type", "ById")
.addAttribute("timeOut", "3")
.addAttribute("value", "\\\\div[@id]").addText("InputButton");
writer.write(document);
writer.close();
} }

定义一个readXMLDocument 方法,返回一个hashMap用来和页面元素名字和Locator对象match起来,也算是一种关键字驱动.

传入的两个参数分别是library的路径和对应的page

那么怎么获取page的class路径?

可以通过反射机制获取:

locatorMap = xmlUtils.readXMLDocument(path,
this.getClass().getCanonicalName());

这样每次只按照page对象去加载其页面的Locator对象,而不是一次性全部加载到内存

hashMap可以通过key去获取Locator,这样也是极好的,比之前二维数组全部遍历好多了

封装一个basePage去处理Locator对象

package com.dbyl.libarary.utils;

import java.io.IOException;
import java.util.HashMap; import org.openqa.selenium.Alert;
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.Select;
import org.openqa.selenium.support.ui.WebDriverWait; public class BasePage { protected WebDriver driver;
// protected String[][] locatorMap;
HashMap<String, Locator> locatorMap;
String path = "C:/Users/Young/workspace/Demo/src/com/dbyl/libarary/pageAction/UILibrary.xml";
protected Log log = new Log(this.getClass()); protected BasePage(WebDriver driver) throws Exception {
this.driver = driver;
log.debug(this.getClass().getCanonicalName());
// locatorMap = ReadExcelUtil.getLocatorMap();
locatorMap = xmlUtils.readXMLDocument(path,
this.getClass().getCanonicalName());
} protected void type(Locator locator, String values) throws Exception {
WebElement e = findElement(driver, locator);
log.info("type value is: " + values);
e.sendKeys(values);
} protected void click(Locator locator) throws Exception {
WebElement e = findElement(driver, locator);
log.info("click button");
e.click();
} protected void select(Locator locator, String value) throws Exception {
WebElement e = findElement(driver, locator);
Select select = new Select(e); try {
log.info("select by Value " + value);
select.selectByValue(value);
} catch (Exception notByValue) {
log.info("select by VisibleText " + value);
select.selectByVisibleText(value);
}
} protected void alertConfirm() {
Alert alert = driver.switchTo().alert();
try {
alert.accept();
} catch (Exception notFindAlert) {
throw notFindAlert;
}
} protected void alertDismiss() {
Alert alert = driver.switchTo().alert();
try {
alert.dismiss();
} catch (Exception notFindAlert) {
throw notFindAlert;
}
} protected String getAlertText() {
Alert alert = driver.switchTo().alert();
try {
return alert.getText();
} catch (Exception notFindAlert) {
throw notFindAlert;
}
} 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:
log.debug("find element By xpath");
e = driver.findElement(By.xpath(locator.getElement()));
break;
case id:
log.debug("find element By id");
e = driver.findElement(By.id(locator.getElement()));
break;
case name:
log.debug("find element By name");
e = driver.findElement(By.name(locator.getElement()));
break;
case cssSelector:
log.debug("find element By cssSelector");
e = driver.findElement(By.cssSelector(locator.getElement()));
break;
case className:
log.debug("find element By className");
e = driver.findElement(By.className(locator.getElement()));
break;
case tagName:
log.debug("find element By tagName");
e = driver.findElement(By.tagName(locator.getElement()));
break;
case linkText:
log.debug("find element By linkText");
e = driver.findElement(By.linkText(locator.getElement()));
break;
case partialLinkText:
log.debug("find element By 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
log.error("can't find element "
+ locator.getElement());
return null;
} } });
return element; } /**
* @author Young
*
* @param locatorName
* @return
* @throws IOException
*/
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);
locator = locatorMap.get(locatorName);
if (locator == null) {
locator = new Locator(locatorName);
}
return locator; }
}

接下来就可以在pageAction使用,如果使用页面跳转,可以使用反射机制,封装一个PageFactory,根据传入的Page类class创建对象

PageFactory如下:

package com.dbyl.libarary.utils;

import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException; import org.openqa.selenium.WebDriver; public class PageFactory {
public synchronized static Object getPage(Class<?> key,WebDriver d)
throws ClassNotFoundException, NoSuchMethodException, SecurityException, IllegalArgumentException, InvocationTargetException {
String test = key.getCanonicalName();
System.out.println(test);
Class<?> clazz = Class.forName(test);
Object obj = null;
try {
Constructor<?> constructor = clazz.getConstructor(WebDriver.class);
obj = constructor.newInstance(d); } catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
return obj; } }

使用方法:

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 (HomePage) PageFactory.getPage(HomePage.class, getDriver());
}

这样,这个框架能够实现一些基本操作,下一步还需要实现失败重试截图,配合虚拟机

下载地址:https://github.com/tobecrazy/Demo

selenium测试框架使用xml作为对象库的更多相关文章

  1. selenium测试框架篇,页面对象和元素对象的管理

    前期已经做好使用Jenkins做buildhttp://www.cnblogs.com/tobecrazy/p/4529399.html 做自动化框架,不可避免的就是对象库. 有一个好的对象库,可以让 ...

  2. selenium测试框架篇

    做自动化框架,不可避免的就是对象库. 有一个好的对象库,可以让整个测试体系: 更容易维护 大大增加代码重用 增加测试系统的稳定性 这里先了解一下我所说的对象库: 所谓的页面对象,是指每一个真是的页面是 ...

  3. selenium 测试框架中使用grid

    之前的测试框架:http://www.cnblogs.com/tobecrazy/p/4553444.html 配合Jenkins可持续集成:http://www.cnblogs.com/tobecr ...

  4. 『心善渊』Selenium3.0基础 — 2、Selenium测试框架环境搭建(Windows)

    目录 1.浏览器安装 2.浏览器驱动下载 (1)ChromeDriver for Chrome (2)Geckodriver for Firefox (3)IEDriverServer for IE ...

  5. python webdriver 测试框架-数据驱动xml驱动方式

    数据驱动xml驱动的方式 存数据的xml文件:TestData.xml: <?xml version="1.0" encoding="utf-8"?> ...

  6. 《Selenium自动化测试实战:基于Python》Selenium自动化测试框架入门

    第1章  Selenium自动化测试框架入门 1.1  Selenium自动化测试框架概述 说到目前流行的自动化测试工具,相信只要做过软件测试相关工作,就一定听说过Selenium. 图1-1是某企业 ...

  7. Spring TestContext测试框架搭建

    同样是测试,JUnit和Spring TestContext相比,Spring TestContext优势如下: 1.Spring TestContext可以手动设置测试事务回滚,不破坏数据现场 2. ...

  8. python3+selenium框架设计02-自动化测试框架需要什么

    什么是自动化测试框架 自动化测试框架能够提供便利给用户高效完成一些事情,比如,结构清晰开发脚本,多种方式.平台执行脚本,良好的日志和报告去跟踪脚本执行结果. 关于自动化测试框架的定义有很多,在我大致理 ...

  9. Selenium 4 Python的最佳测试框架

    随着Python语言的使用越来越流行,基于Python的测试自动化框架也越来越流行.在项目选择最佳框架时,开发人员和测试人员会有些无法下手.做出选择是应该判断很多事情,框架的脚本质量,测试用例的简单性 ...

随机推荐

  1. Ext分页实现(前台与后台)

    Ext分页实现(前台与后台)Spring+Mybatis 一.项目背景 关于Ext的分页网上有很多博客都有提到,但是作为Ext新手来说,并不能很容易的在自己的项目中得以应用.因为,大多数教程以及博客基 ...

  2. jQuery之回调对象

    1. jQuery 1.7 版本中新增的 jQuery.Callbacks() 函数返回一个全能的对象,此对象对管理回调列表提供了强大的方式.它能够增加.删除.触发.禁用回调函数. 2. callba ...

  3. 【USACO 3.2】Sweet Butter(最短路)

    题意 一个联通图里给定若干个点,求他们到某点距离之和的最小值. 题解 枚举到的某点,然后优先队列优化的dijkstra求最短路,把给定的点到其的最短路加起来,更新最小值.复杂度是\(O(NElogE) ...

  4. UEFI模式安装Win10和Linux双系统

    最近心血来潮,想装一个Linux.Windows双系统,吸取上次安装的经验,这次一定都要使用UEFI模式启动,需要注意的是必须是支持此种启动模式的系统(一般解压之后都有efi文件夹不需要刻录),这次遇 ...

  5. 疯狂JAVA16课之对象与内存控制

    java内存管理分为两个方面:内存分配和内存回收.这里的内存分配特指创建java对象时JVM为该对象在对内存中所分配的内存空间.内存回收指的是当该java对象失去引用,变成垃圾时,JVM的垃圾回收机制 ...

  6. winform总结3> 有趣的bat/winform程序完成自己的任务,然后把自己删除

    在winform的开发过程中往往会有这样的应用场景,执行完成某任务之后,程序需要把本身删除掉.比如卸载.分享一个比较简单实现. 思路就是利用批处理,关闭文件后执行bat,bat执行删除主文件,然后删除 ...

  7. 【JavaWeb】Spring+SpringMVC+MyBatis+SpringSecurity+EhCache+JCaptcha 完整Web基础框架(四)

    SpringSecurity(1) 其实啊,这部分我是最不想写的,因为最麻烦的也是这部分,真的是非常非常的麻烦.关于SpringSecurity的配置,让我折腾了好半天,网上的配置方式一大把,但总有一 ...

  8. Mac安装mysql

    ### 第一步 安装后一定要记住初始密码 ### 第二步 打开终端 cd /usr/local/mysql/bin ./mysql -u root -p #输入初始密码 set password = ...

  9. Spring Boot中的事务管理

    原文  http://blog.didispace.com/springboottransactional/ 什么是事务? 我们在开发企业应用时,对于业务人员的一个操作实际是对数据读写的多步操作的结合 ...

  10. CentOS 7.0编译安装Nginx1.6.0+MySQL5.6.19+PHP5.5.14

    准备篇: CentOS 7.0系统安装配置图解教程 http://www.osyunwei.com/archives/7829.html 一.配置防火墙,开启80端口.3306端口 CentOS 7. ...