基于Java+Selenium的WebUI自动化测试框架(八)-----读取元素(XML文件)

       我们继续回到自动化测试框架的主线上来,在前面的文章中,我们定义一个页面元素的主要参数有:路径,找寻方式,等待时间,名称,这个四个参数。另外,我们还需要考虑一个问题,就是网站的页面。

举个例子来说,如果A页面上有“新增”,“选择”,“保存”等按钮,B页面上也有“新增”,“选择”,“保存”等按钮,我们应该如何处理这种情况呢?

  当然,有的小伙伴可能会说,我就直接命名为“新增A”,“选择A”,“保存A”,“新增B”,“选择B”,“保存B”就是了。这样当然是可以的。

  但是,在维护自动化脚本的时候,你就会发现最终完成测试用例的时候,元素非常多,查找不方便。而且直接在名字里增加说明的方法,只会让名字越来越长。数据的结构也非常混乱。

如果能够在元素的上一层我们增加一级,加入一个叫做pageName的参数,把一个页面中操作的元素集中起来管理。这样对元素的定义就会方面很多,也不怕名字重复的存在。

  最重要的是,我们平时的语言习惯也是这么说的:“在登录页面上输入用户名为XXX,密码是XXX”。

  那么,我们以什么方式来提供给程序,然后让程序能够处理这些元素呢?

  方式有很多,我们可以把参数变成xml节点的属性,通过xml文件来读取。我们也可以把元素参数写成Excel,通过Excel来读取。甚至,我们可以把这些参数存入MySQL数据库中,通过数据库来读取。

  对于这些读取元素的方法,我们就逐步来实现。在实际运用中,选择最合适自己的那个。

  下面我们先从XML开始。

  首先,让我们来设计一下我们存储元素用的XML文件。新建一个XML文件,eclipse里面在监理XML文件的时候,会自动加上一句,这个是通用基准,知道就好。

其次,我们需要来设计一个WebUI测试用元素的结构。比如:我们当前需要测试的系统是“文档管理系统”,有若干页面,每个页面上有若干元素。那么,我们可以设计我们的XML是如下的结构。

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

<map>

    <page pageName="loginPage">
        
        <position type="id" timeOut="3" value="UserId">用户名输入框position>        
         <position type="id" timeOut="3" value="Password">密码输入框position>        
         <position type="xpath" timeOut="3" value="//button[text()='登录']">登录按钮position>        
         <position type="id" timeOut="3" value="errorDiv">错误提示position>
    page>
    
    <page pageName="mainPage">
        
        <position type="xpath" timeOut="8" value="//*[@id='left']/ul[1]/li[3]">文档登记position>
        <position type="xpath" timeOut="10" value="//*[@id='left']/ul[1]/li[4]">文档查询position>
        <position type="xpath" timeOut="30" value="//*[@id='left']/ul[2]/li[4]">会议资料position>
    page>
    
    <page pageName="docQueryPage">
        <position type="" timeOut="5" value="fra1d34c791-9a30-4438-a2e0-a282f3be0594">iframe1position>
        <position type="xpath" timeOut="3" value="//*[@id='newnav']/tbody/tr[1]/td/a">科研资料平台position>
    page>
    
map>

  那么,可以看到。我们在这里就是用XML文件来构建了我们元素存储的方式。这里,需要说明2个问题。

1.关于timeOut的设置,timeOut在这里的定义是指定等待的时间。因为我们前面在写页面元素操作实现类UIExcutorImpl的时候,查找元素的代码如下:

 try {
       wait.until(ExpectedConditions.presenceOfAllElementsLocatedBy(By.xpath(path)));
       ele = driver.findElement(By.xpath(path));    
 }catch (Exception e) {
       logs.error("findElment ByXpath:" + path + "-failed! NoSuchElement");
       Reporter.log("findElment ByXpath:" + path + "-failed! NoSuchElement");
 }    

    这里,我们使用智能等待的方式,即:等待所有满足该查找条件(xpath)的元素出现,这样一种方式。我们期待程序自己能够查找,比我们自己指定时间要好的多。

    当然,我们也没有把路堵死。在XML文件中,我们依然可以写入timeOut,即等待时间。只是,这个等待时间,并没有为我们的页面操作实现类所调用,因此,这个timeOut在这里设置可以说是无效的。

    然而,如果某个元素,或者某个页面加载的时间实在太长。使得整体的程序失去响应,必须要强制等待元素出现的情况下。这种情况,我们需要重新再写我们的实现类,这时候我们可以在这里使用这个timeOut的值。

    因此,从数据准备的角度来说,我建议这里保留这个timeOut,因为这也算是测试人员准备数据的成果。

 

2.关于记录iframe的情况

  当我们的测试页面需要制定iframe的时候,即切换至另一块区域的情况下。我们需要把iframe的code(iframe的code一般不具备可读性),作为页面元素给记录下来,便于使用。

虽然具体在网页上,它并没有一个具体位置,但是,我们依然可以把它作为页面元素来处理。只是处理调用的方法和普通的页面元素不一样而已。

  

       关于使用Java来读取xml文件,首先我们还是要导入一个JAR包:dom4j-1.6.1.jar。下载地址:https://mvnrepository.com/artifact/dom4j/dom4j

  接下来,我们开始写一个读取XML的类。

  这个类的思路是:读取一个xml文件,按照pageName进行查找,并遍历该pageName节点下的节点,读取节点属性和名称,按照页面元素构造函数的形式,存入HashMap集合并返回。

package webui.xUtils;

import java.io.File;
import java.util.HashMap;
import java.util.Iterator;

import org.dom4j.Attribute;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.testng.Reporter;

import webui.xUtils.Position.ByType;

public class XmlReadUtil {
    /**读取页面配置文件
     *  @param xmlUrl     *            
     *  页面配置文件路径     * 
     *  @param pageName     
     *  页面名称     */    
    static logUtil logs = new logUtil(XmlReadUtil.class);
    public static HashMap readXMLDocument(String xmlUrl, String pageName) throws Exception {
    //创建一个哈希Map,里面的键值对为(名字,元素) HashMap
positionMap = new HashMap<>();
    //判断XML文件是否存在 File file
= new File(xmlUrl); if (!file.exists()) { logs.error("can't find " + xmlUrl); Reporter.log("can't find " + xmlUrl);} else { // 创建SAXReader对象 SAXReader sr = new SAXReader(); // 读取xml文件转换为Document Document document = sr.read(file); // 获取所有根节点元素对象 Element root = document.getRootElement(); Iterator rootIte = root.elementIterator(); Position position = null; // 遍历根节点 while (rootIte.hasNext()) { Element page = (Element) rootIte.next(); // 节点属性,忽略大小写比较 if (page.attribute(0).getValue().equalsIgnoreCase(pageName)) { Iterator pageIte = page.elementIterator(); // 找到pageName后遍历该page内各个节点 while (pageIte.hasNext()) { String type = ""; String timeOut = ""; String value = ""; String positionName = ""; Element ele = (Element) pageIte.next(); positionName = ele.getText(); Iterator positionIte = ele.attributeIterator(); // 遍历单个标签内的元素 while (positionIte.hasNext()) { Attribute attribute = (Attribute) positionIte.next(); String attributeName = attribute.getName(); if (attributeName.equals("type")) { type = attribute.getValue(); } else if(attributeName.equals("value")){ value = attribute.getValue(); }else { timeOut = attribute.getValue(); } }
                //封装页面元素 position
= new Position(value,Integer.parseInt(timeOut),getType(type),positionName.trim());
                //将页面元素加入哈希Map的集合 positionMap.put(positionName.trim(), position); }
break; } } } return positionMap; }   //从读取的type属性的值,来定义寻找元素的方法 private static ByType getType(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; } }

  这样,这个读取XML文件的类就完成了。接下来我们可以使用这个类来作成一个基础页面类。

       

你可能感兴趣的:(基于Java+Selenium的WebUI自动化测试框架(八)-----读取元素(XML文件))