基于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文件的时候,会自动加上一句<?xml version="1.0" encoding="UTF-8"?>,这个是通用基准,知道就好。
其次,我们需要来设计一个WebUI测试用元素的结构。比如:我们当前需要测试的系统是“文档管理系统”,有若干页面,每个页面上有若干元素。那么,我们可以设计我们的XML是如下的结构。
<?xml version="1.0" encoding="UTF-8"?>
<map><!-- 文档管理系统元素 -->
<page pageName="loginPage"><!-- 登录页面 -->
<!--position lists -->
<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 lists -->
<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">iframe1</position>
<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<String, Position> readXMLDocument(String xmlUrl, String pageName) throws Exception {
//创建一个哈希Map,里面的键值对为(名字,元素)
HashMap<String, Position> 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文件)的更多相关文章
- 基于Java+Selenium的WebUI自动化测试框架(一)---页面元素定位器
对于自动化测试,尤其是UI的自动化测试.是很多做黑盒功能测试的同学,入门自动化测试一个最为直观的或者说最容易理解的途径之一. 对于手工测试和自动化测试的优劣,网上有很多论述,在这里不作展开讨论.但是, ...
- 基于Java+Selenium的WebUI自动化测试框架(十四)-----使用TestNG的Sample
到目前为止,我们所写的东西,都是集中在如何使用Selenium和Java来定位和读取元素.那么,到底如何具体开展测试,如何实现参数化,如何实现判定呢?下面,我们来看看Java应用程序的测试框架吧. 当 ...
- 基于Java+Selenium的WebUI自动化测试框架(六)---浏览器初始化
本篇我们来讨论,如何写一个浏览器初始化的类.在写之前,先思考一下,我们需要一个什么样的初始化? 先来看看使用原生的Java + selenium是怎么做的.(以firefox为例) System.se ...
- 基于Java+Selenium的WebUI自动化测试框架(十)-----读取Excel文件(JXL)
之前,我们使用了读取XML文件的方式来实现页面元素的读取,并做成了基础页面类.下面,我们来进行一些扩展,通过Excel来读取页面元素. Excel的使用,大多数人应该都不陌生.那么Java读取Exce ...
- 基于Java+Selenium的WebUI自动化测试框架(九)-----基础页面类(BasePage)
上篇我们写了java读取xml文件的类,实现了可以从xml文件读取元素的方式.那么,接下来我们需要考虑一个问题.我们拿了这些元素之后怎么去操作呢? 先来看看我们手工测试的时候是怎么进行的. 双击浏览器 ...
- 基于Java+Selenium的WebUI自动化测试框架(十三)-----基础页面类BasePage(Excel)
前面,我们讲了如何使用POI进行Excel的“按需读取”.根据前面我们写的BasePageX,我们可以很轻松的写出来基于这个“按需读取”的BasePage. package webui.xUtils; ...
- 基于Java+Selenium的WebUI自动化测试框架(五)------页面操作实现类
在编写完Log类和监听类之后,终于要回到正轨上来了.我们继续开始写UIExcutor的实现类. PS:如果你想让你的报告更加美观一些.推荐使用reportNG这个jar包. 在项目中导入reportn ...
- 基于Java+Selenium的WebUI自动化测试框架(四)-----设置监听类
基于上一篇的内容,这里我们开始写监听类Listener.我这里写监听类的思路是,继承TestListenerAdapter这个类,然后对其中的方法进行重写.网上也有很多资料,建议先学习一下,然后写出来 ...
- 基于Java+Selenium的WebUI自动化测试框架(三)------记录LOG
在有了Position类和接口类之后,我们是不是立刻就要着手开始写实现类了呢?按照一般的顺序是这样.但是,我们这里先停一下.原因有二: 1)既然是写一个框架,我们希望总体的功能上是全面的.实现类中,我 ...
随机推荐
- SpringMVC:学习笔记(11)——依赖注入与@Autowired
SpringMVC:学习笔记(11)——依赖注入与@Autowired 使用@Autowired 从Spring2.5开始,它引入了一种全新的依赖注入方式,即通过@Autowired注解.这个注解允许 ...
- AWS 数据库(七)
数据库概念 关系型数据库 关系数据库提供了一个通用接口,使用户可以使用使用 编写的命令或查询从数据库读取和写入数据. 关系数据库由一个或多个表格组成,表格由与电子表格相似的列和行组成. 以行列形式存储 ...
- didSelectRowAtIndexPath方法无响应解决办法
tableview的代理事件didSelectRowAtIndexPath失效,可能有三个原因: 1.没有设置tableview的Delegate 需要设置tableview的代理才可以响应代理事件 ...
- 030 Android 第三方开源下拉框:NiceSpinner的使用+自定义Button样式+shape绘制控件背景图+图片选择器(selector)
1.NiceSpinner下拉框控件介绍 Android原生的下拉框Spinner基本上可以满足Android开发对于下拉选项的设计需求,但现在越来越流行的下拉框不满足于Android原生提供的下拉框 ...
- java中selenium判断某个元素是否存在
selenium工具 直接通过findElement方法获取某个元素,如果该元素不存在肯定会报错,selenium又没有可以判断该元素是否存在的方法 于是我们可以手写一个工具类,来判断这个元素是否存在 ...
- WUSTOJ 1320: 饭卡(Java)动态规划-背包
题目链接:
- DBA职责和任务
DBA守则在对生产环境进行修改前,一定要进行备份,一定要在测试环境进行测试,否则不要进行轻易的更改一次尽量只做一件事,不要受环境影响 DBA的十大任务1.了解和掌握硬件环境2.规划数据库3.安装数据库 ...
- 【优先队列】Function
Function 题目描述 wls有n个二次函数Fi(x)=aix2+bix+ci(1≤i≤n).现在他想在且x为正整数的条件下求的最小值.请求出这个最小值. 输入 第一行两个正整数n,m.下面n行, ...
- PHP Math函数
abs() 绝对值. acos() 反余弦. acosh() 反双曲余弦. asin() 反正弦. asinh() 反双曲正弦. atan() 反正切. atan2() 两个参 ...
- 第二次用map23333
度熊所居住的 D 国,是一个完全尊重人权的国度.以至于这个国家的所有人命名自己的名字都非常奇怪.一个人的名字由若干个字符组成,同样的,这些字符的全排列的结果中的每一个字符串,也都是这个人的名字.例如, ...