写在前面 研究iOS的自动化测试也有些日子了,刚开始的时候,一直苦于找不到什么好的资料,只能从Apple的官网查阅相关的API文档,只可惜,Apple对开发者来说实在是不怎么友好,文档写得相当的粗略,对于初学者来说有一定的难度。 本来是打算自己动手写一篇关于iOS的UI自动化测试的入门级别的介绍性文档的,但想起来后面在具体解决一些问题的时候,收藏一篇很好的Blog,很全面地介绍了如何使用UIAutomation的JavaScript Libraries做iOS程序的自动化测试。如果作者早点看到这篇文章,应该要少走一些弯路,这里没有创意性的它他翻译成中文,希望对你们有一些帮助。 快速入门 自动化测试代码可以“在你的睡着的时候”很好地帮你测试你的应用程序。它可以让你能够快速地跟踪你程序中的回归和性能方面的问题,这样你就不用担心你新增的功能会影响到你之前已经完成开发的程序了。 随着iOS4.0的发布,苹果公司同时发布了一个名为UIAutomation的测试框架,它可以用来在真实设备和iPhone模拟器上执行自动化测试。但官方关于UIAutomation的文档相当的有限,在网络上也没有太多的资源可以查找的。本文将向你展示你如何将UIAutomation整合到你的工作流程当中去。 作为基础知识的准备,你可以先看一下苹果公司关于UIAutomation的文档,另外还有一篇快速入门的介绍苹果Instruments的文档也值得看看,当然,如果你有一个免费的Apple开发者账号的话,你可以看一下WWDC 2010 - Session 306 – 使用Instruments进行用户界面自动化测试的幻灯片或者视频。 除此之外,包括在Xcode中的OCUnit测试框架也可以用来为你的应用程序编写单元测试。 1. 你的第一个UIAutomation测试脚本 UIAutomation的功能测试代码是用Javascript编写的。UIAutomation和Accessibility有着直接的关系,你将用到通过标签和值的访问性来获得UI元素,同时完成相应的交互操作。 下面让我们来编写我们的第一段测试代码。 使用iOS模拟器 1. 下载示例应用程序TestAutomation.xcodeproj,并打开它。这个项目是一个很简单的包含2个tab的tabbar应用程序。 2. 确保选中如下图所示的“TestAutomation > iPhone 5.0 Simulator”模式(或许你已经切换成5.1了,因此它可能是iPhone5.1模拟器)。 3. 启动Instruments(Product > Profile),或者通过?I。 4. 选择左边的iOS Simulator,然后再选择Automation模板,然后点击“Profile”。 5. Instruments就已经启动好后,然后直接开始录制了。这里先停止录制,(红包按钮或者?R)。 6. 在左边的Scripts窗口,点击“Add > Create”创建新的脚本。 7. 在脚本编辑器里,输入下面的代码 var target = UIATarget.localTarget();var app = target.frontMostApp();var window = app.mainWindow();target.logElementTree(); |
8. 重新运行这段脚本?R(不需要保存)。脚本跑起来后,你可以在日志打完后停止它。 赞一个!我们就这样完成了我们的第一个UIAutomation测试用例。 使用iOS设备 你除了将你的测试用例运行模拟器上,也可以将它运行在一个真实的设备上。不过,自动化测试用例只能运行在支持多任务的:iPhone 3GS,iPad,iOS > 4.0等设备上。遗憾的是不管iPhone 3G的系统版本是什么,都不支持。 下面是如何操作: 1. 通过USB接口连接上你的iPhone。 2. 选择 “TestAutomation > iOS Device”模式。 3. 确保Developper profile设置成Release模式(而不是Ad-Hoc Distribution profile)。默认情况下,profiling是设置成Release模式的(因为没有必要将profile设置成Debug模式)。 4. 启动测试 (I) 5. 后面的步骤请参考前面模拟器部分。 2. 处理UIAElement和元素可访问性(Accessibility) UIAElement层次结构 Accessibility和UIAutomation有密切的联系:如果一个控件的Accessibility是可以被访问的,你就可以设置和读取它的值,作相关的操作,而当一个控件的Accessibility不可见时,你就没有办法通过automation访问它。 你可以通过Interface Builder,或者通过在程序里设置isAccessibilityElement属性的方式来设置一个控件的Accessibility或者可被自动化。当你设置container view(即:一个视图包含其它的UIKit元素)的accessibility时,你必须注意。你设置了整个View的accessibility将会“隐藏”它的子视图的accessibility,例如:在示例项目中,你不能将outlet视图设置成可访问的,否则它所有的子控件将都不可以访问了。在任何时候,logElementTree都是你忠实的朋友:它将当前界面的所有可被访问的元素都打印在日志里。 每一个可以被访问的UIKit控件都可以用一个Javascript对象来描述,它就是一个UIAElement。UIAElement有几个属性:name, value, elements, parent。你的主窗口包含很多的控件,它们是以UIKit层次的方式定义的,这些UIKit层次结构对应的是UIAElement的层次树。例如:前面的测试代码中,通过调用logElementTree,我们可以得到如下面所示的树结构: +- UIATarget: name:iPhone Simulator rect:{{0,0},{320,480}}| +- UIAApplication: name:TestAutomation rect:{{0,20},{320,460}}| | +- UIAWindow: rect:{{0,0},{320,480}}| | | +- UIAStaticText: name:First View value:First View rect:{{54,52},{212,43}}| | | +- UIATextField: name:User Text value:Tap Some Text Here ! rect:{{20,179},{280,31}}| | | +- UIAStaticText: name:The text is: value:The text is: rect:{{20,231},{112,21}}| | | +- UIAStaticText: value: rect:{{145,231},{155,21}}| | | +- UIATabBar: rect:{{0,431},{320,49}}| | | | +- UIAImage: rect:{{0,431},{320,49}}| | | | +- UIAButton: name:First value:1 rect:{{2,432},{156,48}}| | | | +- UIAButton: name:Second rect:{{162,432},{156,48}} |
|