selenium测试框架使用xml作为对象库

之前已经写过一篇:

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

时间: 2024-12-15 01:49:10

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

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

前期已经做好使用Jenkins做buildhttp://www.cnblogs.com/tobecrazy/p/4529399.html 做自动化框架,不可避免的就是对象库. 有一个好的对象库,可以让整个测试体系: 更容易维护 大大增加代码重用 增加测试系统的稳定性 这里先了解一下我所说的对象库: 所谓的页面对象,是指每一个真是的页面是一个对象. 比如zhihu的登陆页面是一个页面对象,http://www.zhihu.com/#signin 这个页面对象主要包含一个输入邮箱的输入框(一个元素对

selenium测试框架篇

做自动化框架,不可避免的就是对象库. 有一个好的对象库,可以让整个测试体系: 更容易维护 大大增加代码重用 增加测试系统的稳定性 这里先了解一下我所说的对象库: 所谓的页面对象,是指每一个真是的页面是一个对象. 比如zhihu的登陆页面是一个页面对象,http://www.zhihu.com/#signin 这个页面对象主要包含一个输入邮箱的输入框(一个元素对象),一个输入密码的密码框 一个登陆框.当然,zhihu不止一个页面,有无数页面,每一个页面都可以封装为一个对象.而每个 页面的元素,也可

selenium 测试框架中使用grid

之前的测试框架:http://www.cnblogs.com/tobecrazy/p/4553444.html 配合Jenkins可持续集成:http://www.cnblogs.com/tobecrazy/p/4529399.html 在测试框架中使用Log4J 2 :http://www.cnblogs.com/tobecrazy/p/4557592.html 首先介绍一下grid ,selenium grid 是一种执行测试用例时使用的包含不同平台(windows.Linux.Androi

selenium测试框架(java) 版本演化一

selenium的自动化测试代码应该如何组织?  如链接:https://code.google.com/p/selenium/wiki/PageObjects  这里提供了一种PageObject的设计思想,并且在百度内部给出了一个感觉比较实用的实现.其组织结构思想如下: Page 封装页面元素,以及页面应提供的服务. 尽量隐藏页面的细节,不要暴露出来. widget 封装Page中的通用的组件. 这里的理念是所有的WebElement都是控件. 通用的页面样式,如导航栏,列表,组合查询框,可

java + selenium测试框架(之等待机制) 版本演化二

使用selenium-ide录制,以及直接用selenium-java.jar写测试用例,你会发现它的执行速度很快.大大超过了手工操作的速度,甚至可能也超过了浏览器加载的速度(比浏览器都快?结果就是找不到元素). 如果页面上确实有某个元素,但是在测试时提示NoSuchElementException,那原因有两个:1,你抓取元素的策略错了:2,执行时元素还没加载出来. 在调用了driver.get(url)之后,为了保证元素能够取到正确初始化,需要增加一个等待加载完成的函数,保证页面完成加载.

Spring TestContext测试框架搭建

同样是测试,JUnit和Spring TestContext相比,Spring TestContext优势如下: 1.Spring TestContext可以手动设置测试事务回滚,不破坏数据现场 2.在测试类中不用手动装配bean,只要一个@Autowired即可自动装配 ----------------分割线--------------------------- 本文记录web project和java project如何使用TestContext测试框架,首先介绍web project 现总

TestNG测试框架在基于Selenium进行的web自动化测试中的应用

这个测试框架可以把写好的测试用例按自定义顺序执行,以Selenium WebDriver自动化测试用例为例: 1.新建一个名为forTestNg的java project,然后创建一个libs文件夹,导入所有和Selenium相关的jar包: 2.安装TestNG,在Eclipse中点击Help->Install New Software,点击Add,Location填写“http://beust.com/eclipse”,然后点击OK: 之后勾选TestNG,点击Next进行安装即可: 之后点

集成C#测试框架和Selenium对于Web系统实现自动化测试

系统环境: 软件需求: Visual C# 2010,Mozilla Firefox,Selenium 硬件需求: Pentium III 450以上的CPU处理器,64MB以上的内存,200MB的自由硬盘空间 内容简介: 1. 利用Spy++进行Windows对象识别,查找Windows计算器中的3类不同的对象,列出这些对象的常规属性. 2. 利用Selenium测试脚本录制以下操作: (1) 在Firefox地址栏中输入淘宝网主页网址http://www.taobao.com/,回车载入网页

无废话Android之android下junit测试框架配置、保存文件到手机内存、android下文件访问的权限、保存文件到SD卡、获取SD卡大小、使用SharedPreferences进行数据存储、使用Pull解析器操作XML文件、android下操作sqlite数据库和事务(2)

1.android下junit测试框架配置 单元测试需要在手机中进行安装测试 (1).在清单文件中manifest节点下配置如下节点 <instrumentation android:name="android.test.InstrumentationTestRunner" android:targetPackage="com.example.demo1" /> 上面targetPackage指定的包要和应用的package相同. (2)在清单文件中ap