APP UI Automation Framework
一个基于 Appium 1.8.1、TestNG,Page Object 模式开发的 UI 自动化测试框架
介绍文档
结构图
基本功能
每秒生成一次截图
通过 xml 配置待执行的测试用例
通过 yml 指定待执行测试的设备及 Appium 端口
用例执行失败自动重试,且重试次数可配置
用例执行失败时自动截图
生成测试报告 (NGReport)
支持自定义配置项
设计目标
用一套代码执行 Android/iOS 测试用例
Test case 层的代码高度利用,只需要考虑业务逻辑,无需关心系统平台及如何查找元素
以下代码在iOS和Android上均可运行
//打开我的朋友圈
public void showMyMoment(){
//打开微信主页面,点击"我"
WeiXinMainPage.verify()
.clickMeButton();
//校验"我"页面,打开"朋友圈"
WeiXinMePage.verify()
.clickMoment();
//校验"朋友圈页面",下划一段距离,然后打开带图片的朋友圈
WeiXinMomentPage.verify()
.scroll()
.clickMyMoment();
Driver.sleep(10);
}
设计理念
应用 Page Object 模式提高 UI 页面操作代码的复用度
用 Driver 类封装所有用到的 Appium API, 框架中其它类只通过 Driver 调用 Appium 的方法,这种作法会有以下两点好处:
一、屏蔽对 Appium API 的依赖,如果 Appium 的某个 API 官方废弃了,只需修改 Driver 类封装的相应方法即可
二、如果将 Appium 换成 Macaca 或其它框架,除了改动 Driver 类 其它类无需改动
在 Driver 中用 findElementById 等封装对 iOS 和 Android 的元素查找,提高代码的复用,尽可能的避免 iOS 与 Android 因查找元素方式不同而写相似的代码
该框架适用于同一个 APP, Android 和 iOS UI 结构基本一致的情况
一些原则
Page 类的构造函数用 Verify 代替
Page 类的构造函数用过 findElementByID 等来 检查当前页面是不否为期望的 Page
依照 SRP 原则,Page 类内的函数 只返回当前类实例(this) 或 void, 不返回其它页面的对象,确保每个 Page 与依赖于任何其它 Page,提高 Page 类的复用度
//朋友圈的Page类
public class WeiXinMomentPage extends BasePage {
//能过静态方法返回页面实例
public static WeiXinMomentPage verify(){
if( !Util.isAndroid() ) {
//默认情况下写的Page类是Android的UI
//若Android与iOS UI上有差异,需继承Android的Page类再写个iOS Page
return new WeiXinMomentPageiOS();
}
return new WeiXinMomentPage();
}
//不允许调用构造函数
protected WeiXinMomentPage(){
Driver.findElementByText(getRes("MOMENT_PAGE_ME_TEXT"));
}
//所有成员函数只返回this或void,确保每个Page类的独立性,不依赖于任何其它Page类
public WeiXinMomentPage scroll(){
Driver.scrollUp();
return this;
}
public WeiXinMomentPage clickMyMoment(){
MobileElement elem = Driver.findElemByIdWithoutException (getRes("MY_POST_PAGE_MOMENT_PIC_ID"));
if(elem == null){
elem = Driver.findElementById(getRes("MY_POST_PAGE_MOMENT_ARTICLE_ID"));
}
elem.click();
return this;
}
}
类
Driver : 封装所有用到的 Appium 方法。作用屏幕对 Appium 的依赖、提供更方便的函数。
BasePage : 所有 Page 类的基类
BaseTest : 所有 Test 类的基类
ConfigUtil : 读取工程配置文件
ResourceUtil : 读取资源配置文件
Util : 工具类,提供一些能用方法
PageUtil : 封装进入某个页面的方法,方便复杂 test case 的编写
TestListener : 监听测试结果,用例执行失败时截图
配置文件
Config.yml 运行测试时的一些配置项 如包名,重试次数等等。 详见 Config.ym 内的注释
资源文件(具体使用方法见 demo)
为每个元素新建一个便于辨识的名字,用这个名字统一 Android/iOS 待查找元素, 然后将不同系统找中该名字的元素对应的值写入相应的 RES.yml 中
AndroidRES.yml 写入 Android 元素查找时需要用到的值
IOSRES.yml 写入 iOS 元素查找时需要用到的值
AndroidRES.yml
MAIN_PAGE_WEIXIN_TEXT: '微信'
MAIN_PAGE_CONTACT_TEXT: '通讯录'
MAIN_PAGE_DISCOVER_TEXT: '发现'
MAIN_PAGE_ME_TEXT: '我'
ME_PAGE_MY_POST_TEXT: '相册'
MOMENT_PAGE_ME_TEXT: '我的相册'
MY_POST_PAGE_MOMENT_PIC_ID: 'com.tencent.mm:id/dep'
MY_POST_PAGE_MOMENT_ARTICLE_ID: 'com.tencent.mm:id/yk' IOSRES.yml
MAIN_PAGE_WEIXIN_TEXT: '微信'
MAIN_PAGE_CONTACT_TEXT: '通讯录'
MAIN_PAGE_DISCOVER_TEXT: '发现'
MAIN_PAGE_ME_TEXT: '我'
ME_PAGE_MY_POST_TEXT: '相册'
MOMENT_PAGE_ME_TEXT: '我'
MY_POST_PAGE_MOMENT_PIC_ID: 'visible == true AND type == "XCUIElementTypeStaticText" AND name CONTAINS "月"'
测试用例集
框架通过读取 task 目录下的 xml 运行指定的测试用例
在任务的xml中有四个值需要配置
1. port : Appium 端口
2. udid : 设备ID
3. wdaPort : iOS设备运行的时的WDA port
4. class : 待运行的测试类
测试执行时输入的xml样例
如何运行 demo
demo 实现的功能:打开微信 (若未登录微信,请先手动登录),然后打开朋友圈,查看第一个朋友圈 (带图片的)
启动 Appium,然后运行以下命令
方式一 : 将工程打成 Jar 包,然后运行命令 java -jar UIAutomation-1.0-fat-tests ./task/demo.xml
方式 2 : IDEA 中 右键单击 demo.xml ,选择运行。见下图
参考文档