博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
UI层自动化测试框架(四):对象库层
阅读量:4227 次
发布时间:2019-05-26

本文共 5909 字,大约阅读时间需要 19 分钟。

引言

本章主要介绍自动化测试框架–对象库层。该层是UI自动化中比较关键的一层,设计自动化框架,不可避免的就是对象库,有一个好的对象库,可以让整个测试框架可维护性更高,大大增强了代码的复用性。

讲之前先和大家普及个一概念:PO模式

PO模式

那什么叫PO模式,为什么要用PO模式?引用如下一段话,你就会恍然大悟~

PO模式,全称Page Object模式,是Selenium中的一种测试设计模式,主要是将每一个页面设计为一个Class,其中包含页面中需要测试的元素(按钮,输入框,标题 等),这样在写测试脚本时,可以通过调用页面类来获取页面元素。当页面某个元素id或者位置变化时,这时不用更改测试脚本,只用改下对应的页面类就行了。

上面这段话,总结一下就是:PO就是一个设计模式,将代码以页面为单位进行组织,针对这个页面上的所有信息,相关操作都放到一个类中;从而使具体的测试用例变成了简单的调用和验证操作。

如果你深刻理解了就应该知道了PO对象的好处,当然这只是阐述啦它的可维护性,但它的复用性就更好理解,这里就不多做解释。

对象库的引入

对于上面讲的PO模式,大家会不会有一个疑惑?这样一来一个app有很多page,以DJI GO为例50个左右肯定是有的吧,那这样是不是要设计50个页面类,然后每个页面类中写对应的元素。这样一来单单页面类就写这么多,感觉工程量太大,而且代码的复用性不高。

那有没有什么改进的办法呢?

1.首先定义一个BasePage类,毕竟所有的页面都有共同的东西,每个页面都有元素,每个页面元素都有相应的方法。该类包括一个成员变量 pageName,和封装的的方法。重写它的构造方法,用来初始化成员变量。以后每次调用某个页面时,只用new一个BasePage对象,传入对应的参数pageName,就获得对应页面。

这里写图片描述

package com.dji.object;import java.io.IOException;import java.util.HashMap;import com.dji.utils.AppiumExecutorImpl;import com.dji.utils.Log;import com.dji.utils.XmlUtils;import io.appium.java_client.AppiumDriver;import io.appium.java_client.MobileElement;/** * 封装一个BasePage的类,毕竟所有的页面都有共同的东西,每个页面都有元素,每个页面元素都有相应的方法 *  * @author Charlie.chen * */public class BasePage extends AppiumExecutorImpl {
protected AppiumDriver
driver; protected String pageName; //页面名称 protected String xmlPath; //页面元素路径 protected HashMap
locatorMap; public Log log = new Log(this.getClass()); public BasePage(AppiumDriver
driver,String pageName) throws Exception { super(driver); this.driver = driver; this.pageName=pageName; //获取资源文件page.xml的路径 //xmlPath=System.getProperty("user.dir")+"\\src\\main\\java\\com\\dji\\pageObject\\Page.xml"; xmlPath=BasePage.class.getClassLoader().getResource("page.xml").getPath(); //locatorMap = XmlUtils.readXMLDocument(xmlPath, this.getClass().getSimpleName()); locatorMap = XmlUtils.readXMLDocument(xmlPath, pageName); } public void type(String locatorName, String values) { super.type(getLocator(locatorName), values); log.info("type value is: " + values); } public void click(String locatorName) { super.click(getLocator(locatorName)); log.info("click: "+locatorName); } public String getText(String locatorName) { // TODO Auto-generated method stub return super.getText(getLocator(locatorName)); } public MobileElement findElement(String locatorName) { // TODO Auto-generated method stub return super.findElement(getLocator(locatorName)); } public boolean isElementDisplayed(String locatorName) { // TODO Auto-generated method stub return super.isElementDisplayed(getLocator(locatorName)); } /** * 根据locatorName获取Locator * * @author Charlie.chen * @param locatorName * @return * @throws IOException */ public Locator getLocator(String locatorName) { Locator locator = null; if(locatorMap!=null) { locator = locatorMap.get(locatorName); } return locator; }}

上述代码中有个一个集合locatorMap,主要存储的对应的pageName和Locator内容

2.接下来封装元素,每个元素都有相应的定位地址(xpath路径或css或id),等待时间,定位方式

package com.dji.object;/** * 封装页面元素,每个元素都有相应的定位地址(xpath路径或css或id),等待时间,定位方式 *  * @author Charlie.chen * */public class Locator {
private String address; //定位地址 private int waitSec; //等待时间 private ByType byType; //定位方式 /** * 定位类型枚举 * @author Charlie.chen * */ public enum ByType{ by, xpath, linkText, id, name, className } public Locator() {} /** * Locator构造器,默认定位类型By.xpath * * @author Charlie.chen * @param element */ public Locator(String address) { this.address = address; this.waitSec = 3; this.byType = ByType.xpath; } public Locator(String address, int waitSec) { this.waitSec = waitSec; this.address = address; this.byType = ByType.xpath; } public Locator(String address, int waitSec, ByType byType) { this.waitSec = waitSec; this.address = address; this.byType = byType; } public String getAddress() { return address; } public int getWaitSec() { return waitSec; } public ByType getBy() { return byType; } public void setBy(ByType byType) { this.byType = byType; } public ByType getByType() { return byType; }}

对象库的管理

针对上面的两个类BasePage和Locator,其实就是分别代表页面对象库和元素对象库。关于对象库的管理,就是将对象库中的数据,类似pageName和元素属性id,xpth等分离出来保存在page.xml文件中,这样做到了数据隔离的效果,维护性更高。

page.xml如下

设备
编辑器
天空之城
用户图像
用户名
DJI商城
DJI论坛
礼品卡
上传列表
消息
我的收藏
更多
设置
登录输入账号框
登录输入密码框
登录
返回
使用手机流量上传文件
开启USB调试
重置新手指引
清除数据缓存
多语言
隐私设置
给我们评分
退出DJI账号
取消
确定
DJIGO用户协议

分析一下page.xml中登录页,对应的pageName=“loginPage”,对应的元素名有“登录输入账号框”,“登录输入密码框”,“登录按钮”和对应的定位方式和等待时间。这样是不是一目了然,以后如果页面元素属性发生变化,只用改下以上配置文件即可。关于xml文件的读取,在第三章中有讲过,通过XmlUtils进行读取,将读取的信息保存在HashMap集合locatorMap中。

总结

总结一句话:就是将页面和元素封装在两个类中,然后将对应的数据抽离出来放在xml文件中管理。

对象库大大提高了测试框架的复用性和可维护性,在测试框架中起到核心作用,这里只是我的处理方式,相信还有更简洁更易度的方法,等待大家去挖掘。

下一章主要讲解 自动化测试框架(五):业务层和用例层,敬请期待!!

你可能感兴趣的文章
MySQL的基本管理
查看>>
MySQL 表结构与键值
查看>>
MySQL存储引擎,表记录管理
查看>>
Mysql多表查询语句,授权用户与密码更改
查看>>
MySQL 备份与恢复
查看>>
函数可重入性及编写规范
查看>>
想成为嵌入式程序员应知道的0x10个基本问题
查看>>
可重入函数与不可重入函数
查看>>
关于预处理器的学习
查看>>
Windows CE下操作GPIO的方法(以ARM9 S3C2410为例)
查看>>
s3c2410物理地址和虚拟地址空间
查看>>
VC中常用数据类型转换
查看>>
VC中常用类型转换2
查看>>
windows变量前缀总结(转载)
查看>>
UNICODE编程
查看>>
LPTSTR、LPCSTR、LPCTSTR、LPSTR的意义
查看>>
Visual C++中的ODBC编程
查看>>
AD590的引脚使用
查看>>
VC++工程文件下的各个文件说明
查看>>
VC中常用调试技巧
查看>>