1,Java基础知识,知道类、构造方法、继承这样的基础概念
2,对IOS系统有一定的了解;了解xcode工具
3,会使用Maven进行编译
简介
Athrun以Mobile自动化测试框架为基础,以PC2Mobile为切入点,是淘宝 Mobile测试日常工作必备的平台
目前Athrun支持:
Ø Android上的自动化测试,包括自动化测试框架,持续集成体系。
Ø IOS上的自动化测试,包括:
1. 注入式自动化框架AppFramework;
2. 基于录制的非注入式自动化框架 Athrun_IOS;
3. InstrumentDriver,还有持续集成体系。
AppFramework已经支持socket通信方式。
IOS框架发展历程
图例 1 IOS框架发展历程
1.
注入式框架从无到有,首开先河,通过直接修改开发代码,让测试运行起来,升级日志系统,方便查看运行结果。
• 思路:
– 利用didFinishLaunchingWithOptions
– 构造控件树
– 模拟touch事件
• 优点:
– IOS各版本适用
– Objective-C贴近开发
• 困难:
– 需要修改开发代码
– 运行下个用例前,需要主动返回首页
– Objective-C对测试的学习成本
注:didFinishLaunchingWithOptions
顾名思义。在app开始运行时会调用里面的方法。官方文档的定义是"Tellsthe delegate when the application has launched and may have additional launch options to handle."
基于录制的非注入式自动化框架 Athrun_IOS采用instrument js 工具包,增加稳定性,增加校验功能。增加批量执行。效率提升,从需要注入改代码,到可以直接运行app。运行稳定性提升,增加易用性。
• UIAutomation的调研
– 优点:录制、非注入
– 缺点:IOS 4.0以上支持,操作不稳定
• 我们对UIAutomation的扩展
– 操作扩展
– 校验扩展
– Log转Hudson
• UIAutomation方案的困扰
– 录制难维护
– 低级错误,排错成本高
– 无法单步调试
– 服务端数据准备
纯Java环境编写用例,更好的接入现有测试系统。语法出错排查时间从原来的平均30分钟,减为0。智能感应让编写用例时间缩短30%,学习成本大幅降低。调试功能让出错排查时间缩短50%,从而在很大程度提升效率。
• 特点
– 使用java编写用例
– junit方式运行用例
• 优势
– 自动的语法检查,智能感知
– 支持断点单步调试、变量查看
– 更方便的持续集成和数据准备
InstrumentDriver 简介
Instrument Driver 是 Mobile自动化小组最近实现的基于 instrument,针对 IOS 的自动化测试框架,目前支持 java 语言编写测试用例。
研究过IOS自动化测试的同学肯定对 instrumentUI Automation 有所耳闻,或者已经使用它进行自动化测试实践。IOS4.0 开始,苹果官方提供了 UI Automation 以支持应用的UI自动化测试。不过4.0版本并不支持录制功能,只能根据提供的API文档编写 JavaScript 测试脚本,instrument 驱动脚本在应用上模拟用户行为。
让人兴奋的是,5.0开始,UI Automation 支持录制和回放了。用户在应用上的操作过程被记录下来并生成对应的脚本可以进行回放。虽然录制的脚本回放很不稳定,健壮性不强,录制后需要进行一些简单调整然后加入自己的校验逻辑,但已经很大程度上方便了用例的编写。
自动化测试不是简单的录制回放,脚本运行通过就可以了,而是一整套的流程。instrument 支持批量运行 trace 文件中导入的JavaScript脚本,也支持命令行运行单个脚本,但是这并不能建立一个比较完善的回归体系,从数据准备,到用例编写、调试、维护,回归,运行结果的收集,到测试报表的生成,结果的分析等。
为了从根本上避免上述使用过程中遇到的问题,我们开始想办法脱离 js 编写脚本的方式,通过编写java测试用例,来避免脚本无法单步调试、查看变量值,无自动语法检查、代码智能感知等极大影响自动化测试体验的弊端。java强大的文件读写,数据库操作也让数据驱动和数据准备的实现成为可能。加上java能与丰富的外部工具进行方便的集成,这更坚定了我们采用java实现的决心。
由于IOS系统本身的封闭性,给自动化测试带来了诸多挑战,要么在应用中注入测试代码进行自动化测试,要么使用官方的 instrument。两种方式各有利弊,怎样在这之中寻求一种更好的方式呢?通过调研发现 instrument 提供的一个在脚本中能够调用外部shell的“漏洞”,让我们想法的实现成为可能。基于此,有了 Instrument Driver 的实现。
InstrumentDriver
整体框架图
说明:
框架分为Server端和Client端,双方进行socket通信传递消息:
l Client端(Mobile)负责请求测试步骤运行,并返回运行结果;
l Server端(Java用例)负责响应Client请求并接受测试步骤的运行结果。
1.5 InstrumentDriver功能特点
1、 C/S 模式运行。
框架分为Server端和Client端,双方进行socket通信传递消息:Client端(Mobile)负责请求测试步骤运行,并返回运行结果;Server端(Java用例)负责响应Client请求并接受测试步骤的运行结果。C/S模式的实现,甚至可以脱离Mac在PC上编写、调试测试用例(运行肯定离不开Mac系统),在熟悉的window环境下,让用例编写更加得心应手。
2、 纯Java语言编写测试用例,很好的兼容了instrument js格式的API。
InstrumentDriver用Java实现了各元素类型的之间的继承关系以及各元素类型所提供的操作方法,还扩展了一些更易于使用的操作,如滑动操作等。熟悉instrument js语法格式的测试人员可以很快用java语言实现测试用例。
3、 提供了清晰的控件树状结构打印及便利的元素查找方法。
可以树状结构打印出当前窗口的所有元素或某一元素下的所有子元素。输出属性中不仅包括各元素的基本属性(name,value,label,rect等),更包括代表该元素的guid,用例中使用该guid属性即可代表该元素进行相应操作。findElemenByText及相关重载方法可以很方便的根据元素的显示文本,类型,索引组合查找该元素,极大提升了用例的自描述性和可维护性,也更好的简化了用例的编写。
4、 Debug模式和非Debug模式运行
用例可以debug模式和非debug模式两种方式运行。debug模式通信时传递json对象或数组,返回后实例化为具体对象。可以调试脚本,查看相关对象的属性值。非debug模式仅在需要操作UI元素或获取UI元素属性的时候才通信,较大的提升了运行速度(debug模式的2倍左右)。可以这么认为:用例debug模式通过后,非debug模式也能运行通过。
5、 TestNG方式运行测试用例
InstrumentDriver以大家熟悉的TestNG方式驱动测试用例,具备了TestNG单元测试的所有优点。可以更好结合其它工具进行持续集成和数据准备。如结合svn,maven,Jenkins进行持续集成,通过Excel进行数据准备等。
常用API介绍
• API介绍:
- 面向UI对象
- 支持数组
- 与UI Automation兼容
- 录制的脚本可以运行
• 根节点:
- UIATarget
- static localTarget()
- printElementTree
- scrollUp/Down/Left/Right
- frontMostApp
• UIAApplication
- alert
- keyboard
- UIANavigationBar
- mainWindow
- win=UIATarget.localTarget().frontMostApp().mainWindow()
- UIAWindow(win)
- 继承自UIAElement
- UIAElement
- elements
- T findElementByText(String text, Class<T> elmentType)
- tap
- touchAndHold
Ø 一旦继承了InstrumentDriverTestCase这个类,那么,变量target,app,win就可以直接使用了,分别代表target对象,当前应用,与当前窗口。
Ø UIAElement#findElementByText(Stringtext, Class<T> elementType ),"#"表示是实例方法,该方法返回一个包含text文本的T类型的元素,比如
win.findElementByText("消息",UIAButton.class).tap(),返回一个文本为“消息”的按钮,tap()是单击这个按钮的意思,类似于iPhone上的“摸一下”;还可以在找到的元素的基础上再找另外的元素,相当于在一个子集下寻找一个元素,比如win.navigationBar().findElementByText("取消",UIAButton.class);这行代码将会在当前窗口的顶部导航栏中查找一个按钮。
Ø UIAElement#printElementTree(),比如win.printElementTree(),会打印出当前窗口的所有元素的树结构,这对于确认和定位元素很有帮助。
Ø 延时处理。页面上需要停留时可以使用target.delay(int sec),这个对于等待后端响应有帮助。
Ø 弹窗的捕获与处理,有两种弹出,一是alert弹窗,一是actionsheet。
i. 捕获alert弹窗,可以使用app.alert()捕获,相应的,如果写成
app.alert().printElementTree(),就可以打印出该弹窗的内部元素结构,从而便于进一步的处理。
ii. 捕获actionsheet弹窗,actionsheet是由窗口底部弹起的,可以使用app.actionSheet()捕获,其余的处理同于alert弹窗
Ø 滚动。代码target.scrollUp(),可以向下滚动半屏高度。
Ø 校验。虽然框架的查找方法在找不到控件时会自动让测试失败,但如果你想强制测试失败,或者是其他的校验,可以使用TestNG的Assert类的相关方法来达到目的,比如
l Assert.fail(),强制测试失败。
l Assert.assertEqual(Stringmsg,String expected,String actual),可以用来校验字符串相等,详情请参考Assert类。
Ø 碰到无法侦查的元素怎么办?
用profile命令启动instruments,然后尝试录制一下相关的操作,在生成的js代码中查找线索。
另外,有时间的话请多读读框架的源码
本套框架很容易入门,但随后可能就会发现有些问题比较棘手,比如:
1.头疼的socket超时问题
2.暂未提供某些比较重要的iPhone的界面操作接口,比如,开关,Wi-Fi,滑动删除等等,但这些并不影响我们对常规功能实现自动化。
Instrument Driver 测试环境的搭建
1) 你已经具备了一台mac或者mac mini,并已经安装了mac os 10.7.5或者更高的版本,或者你已经在pc上安装了同样的虚拟机。
因为Maven项目用到的一些文件会放在隐藏文件中,需要设置Mac机显示隐藏文件夹才能查看相关文件。设置方法如下:
打开Mac终端,输入显示隐藏文件夹命令:
defaults write com.apple.finder AppleShowAllFiles-bool true
设置后注销重启Finder。
若要隐藏文件,操作命令如下:
defaults writecom.apple.finder AppleShowAllFiles -bool false
Xcode
直接安装最新的xcode即可,本框架已能兼容iOS6.0。如果已经安装xcode,你可以跳过该部分。
xcode里编译版本有很多中命令,分别适用于不同的目的。本segment只讲一个命令,profile。
1) 编译前的设置。假设已在xcode中打开最新分支,你需要设置三项:
a) 设置target,应设置为“当前工程名>iPhone 5.X simulator”;
b) b.设置打包的网络环境是内网,还是外网,这个不同项目设置不同,这里不予多说,建议到时直接问开发同学;
c) 设置包的签名,这个也因项目而异,这里只给出掌上旺信的设置方法,参见截图,其余项目比如湖畔可以询问开发同学;
注意:b,c的设置都是在“build settings” tab下里设置的。
2) execute profile
a) 一切设置ok后,顶部菜单栏,选择product->profile;
b) B.如果编译无错,有错请开发同学排错,就可以启动instruments了;
c) C.点击profile后,开始启动instruments 及模拟器;
d) D.这里可以开启iPhone自动录放功能的尝试,但这不是重点,有兴趣可以看一下这一步;
e) 录制后的脚本可以在代码区域右键导出,以便日后回放。
f) 如果你打算使用java版的自动化框架,上一步可以帮助你探测元素,但一般情况下我们不需要直接使用instruments,所以现在请退出instruments跟模拟器。到此为止,profile一个版本算是成功了。
3) 查看并拷贝build成功后的包。
a) 找包。第一次build成功后,你未必能找到最终的包,我不保证所有版本的xcode生成的包都跟我说的是一个位置,如果按照下面截图找不到包,建议去询问开发同学。
XCODE
直接安装最新的xcode即可,本框架已能兼容iOS6.0。如果已经安装xcode,你可以跳过该部分。
xcode里编译版本有很多中命令,分别适用于不同的目的。常用一个命令,profile。通过这个按钮,点击 UIAutomator 录制。
下图是Automation录制的脚本截图:
可以看到,脚本非常冗长,只能通过元素的子元素一级级往下查找,很多索引方式生成的脚本自描述性不高,页面稍有变化,不能很快找到对应的脚本进行更改,这样维护成本是很高的。
对比InstrumentDriver 的 java用例,同样功能的用例实现截图如下:
win.findButton("Button").touchAndHold(1); // 点击更多
win.findElementByText("关于我们").tap();
可以看出使用InstrumentDriver框架,你可以通过录制来确定对象的结构,然后通过提供的findElementByText方法可以根据label,name,text来查找对象。也可以通过框架提供的printElementTree方法打印出当前window所有元素, findElementByText 方法能很精确的查找到相应元素。这样根据脚本就知道这一步骤的具体行为,自描述性大大提升,可维护性更好。
这里我们可以根据输出方便的找到需要操作的元素,并且可以直接使用该元素的 guid属性代表该元素,插入用例进行相应的操作。更推荐的做法是使用findElementByText进行定位,假如text(name, value ,label属性)都为空,可以查看父级元素或者更上级元素是否有text属性,然后使用elements() 索引定位,可以最大化缩小范围,使脚本更健壮,可读性更高。
更多内容参见官网:
http://code.taobao.org/p/athrun/src/trunk/
目的:希望给广大读者获取帮助,相互学习一起进步。
说明:本文章禁止用于商业用途,转载时注明出处,解释权归本人所有。