自动化测试是非常有用的测试你的应用程序“睡觉”。它可以使你快速轨道回归和性能问题,并开发新的功能而不打破你的应用令人担忧。
由于iOS 4,苹果发布了一个叫做uiautomation框架,可用于在真正的设备和在iPhone模拟器执行自动化测试。在uiautomation文件很小,没有在网络上有很多资源。本教程将告诉你如何将你的工作流程uiautomation。
最好的开始的指针是苹果文档uiautomation一个很好的快速教程,苹果设备的文件而且,当然,幻灯片/视频2010届WWDC 306自动化用户界面测试仪器。你需要一个免费的开发者帐户访问该资源。
另一个要提到的是OCUnit框架,其中包括在Xcode,可以用来添加单元测试你的应用程序。
uiautomation功能测试是用JavaScript写的。uiautomation和可达性之间有着密切的关联,所以你将使用的辅助标签和数值模拟和检查模拟界面相互作用的结果。
走吧,写我们的第一个测试!
在脚本编辑窗口,点击下面的代码
VaR目标= uiatarget。localtarget();
VaR应用为目标。frontmostapp();
VAR窗口=程序。mainwindow();
;
就是这样à!你写你的第一uiautomation试验!
你也可以用一个真实的设备进行测试,而不是模拟器。自动化测试仅在支持多任务的设备:iPhone 3GS,iPad运行iOS > 4。uiautomation是不可用的iPhone 3G,不管是操作系统版本。
在设备上运行测试:
可达性和uiautomation有很大的关系:如果一个控制可访问性,你将能够获取/设置值上,产生的作用等控制,不是“可见”可不可以通过自动化。
你可以允许访问/自动化控制是否使用界面生成器,或通过设置的属性以编程方式isaccessibilityelement
。你要注意当设置访问容器视图(即一个视图包含其它UIKit元素)。使访问整个视图可以“隐藏”从它的子视图的访问/自动化。例如,在项目中,控制器的视图出口不可,否则子控件不可。如果你有任何问题,logelementtree
你的朋友:把当前所有可见的元素可以访问。
每个UIKit控件可以访问可以通过JavaScript对象表示,uiaelement。uiaelement有几种特性,姓名
,价值
,元素
,父母
。你的主窗口包含了很多控件,它定义了一个框架体系。这uiaelement UIKit层次,对应一个层次。例如,通过调用logelementtree
在之前的测试中,我们有以下的树:
矩形:{ { 20179 },{ 280,31 } }
| | | + uiastatictext:名称:正文:价值:正文:矩形:{ { 20231 },{ 112,21 } }
| | | + uiastatictext:价值:矩形:{ { 145231 },{ } }
155,21 | | | + uiatabbar:矩形:{ { 0431 },{ 320,49 } }
| | | | + uiaimage:矩形:{ { 0431 },{ 320,49 } }
| | | | + uiabutton:名称:第一价值:1矩形:{ { 2432 },{ 156,48 } }
| | | | + uiabutton:名称:二矩形:{ { 162432 },{ 156,48 } }
访问文本字段,你就可以写:
VaR TextField = uiatarget。localtarget()。frontmostapp()。mainwindow() textfields() [ 0 ];
你可以选择一个0或元素名称索引访问元素。例如,以前的文本字段可以也可以这样:
VaR TextField = uiatarget。localtarget()。frontmostapp()。mainwindow()。textfields() [用户文本”];
后来的版本更清晰,应首选。你可以设置一个uiaelement名字无论在界面生成器:
或programmaticaly:
mytextfield.accessibilityenabled =是的;
mytextfield.accessibilitylabel =“”用户文本;
你可以看到现在的可访问性特性所使用的uiautomation针对不同的控件。这是非常聪明的,因为1)只有一个框架的学习;2)写出你的自动化测试,你也要确保你的应用程序是可访问的!所以,每个uiaelement可以通过调用以下函数访问它的孩子:buttons()
,images()
,scrollviews()
,textfields()
,webviews()
,segmentedcontrols()
,sliders()
,statictexts()
,switches()
,tabbar()
,tableviews()
,textviews()
,toolbar()
,toolbars()
等在标签栏的第一个选项卡访问,你可以写:
VaR TabBar = uiatarget。localtarget()。frontmostapp()。tabbar();
VAR TabButton = TabBar buttons() [“第一”;
的uiaelement层次是非常重要的,你要不断地处理它。记住,你可以把层次在你每次调用脚本logelementtree
在uiaapplication:
uiatarget。localtarget()。frontmostapp()。logelementtree();
在模拟器中,你也可以启动辅助检查。启动模拟器,去“设置>一般>辅助功能>可督察并将其设置为'对'。
这个小彩虹盒子是可达性检查。坍塌时,辅助功能是关闭的,当扩展的访问是。激活/ desactivate通达,你只需要点击箭头按钮。现在,去我们的测试应用程序,启动它,并激活督察。
然后,点击文本字段检查姓名
和价值
相关的uiaelement性能(和NSObjectaccessibilitylabel
和accessibilityvalue
属性)。检验员将帮助您调试和编写脚本。
让我们再进一步,模拟用户交互。点击一个按钮,你只需调用tap()
这个元素:
VaR TabBar = uiatarget。localtarget()。frontmostapp()。tabbar();
VAR TabButton = TabBar。buttons() [第一];
/水龙头! Import’ and select TestAutomation/TestUI/Test-1.js">点击“添加”,选择>导入自动化测试/ testui / test-1.js
脚本:
=“第一”){
TabBar。buttons() [第一]。tap();
}
/ / --点击文本文件
uialogger。logMessage(“点击文本字段”);
VaR recipename长名称=“特别配方”;
窗口。textfields() [ 0 ]。setValue(recipename);
目标。延迟(2);
/ / --点击文本文件
uialogger。logMessage(“把键盘”);
APP。logelementtree();
APP。keyboard()。buttons() [“回报”]。tap();
VaR textvalue =窗口。statictexts() [“recipename”]。value();
如果(textvalue = = = recipename){
uialogger。logpass(testname);
这个脚本启动的应用程序,如果不选择选择第一个选项卡,设置文本字段的值为“一方”特别长的名字和解散的键盘。新的功能的通知:延迟(数的时间间隔)
在uiatarget允许你将一些延迟之间的相互作用,logMessage(字符串)
在uialogger可用于测试输出日志logpass(字符串)
在uialogger表明你的脚本已成功完成。
你还可以看到如何访问不同的键盘上的按钮,点击它 应用程序。keyboard()。buttons() [“回归”tap() ];
现在,你已经基本知道你可以写一些测试。你会发现很快在你的测试中有大量的冗余和胶水代码,你通常会重写代码一样:
VaR目标= uiatarget。localtarget();
VaR应用为目标。frontmostapp();
VaR应用程序窗口=;
这就是为什么我们要使用一个小的JavaScript库,简化了写作uiautomation试验。去https://github.com/alexvollmer/tuneup_js,让图书馆和复制调整文件夹一边测试文件夹。现在,我们可以通过调整重写test1.js
=“第一”){
TabBar。buttons() [第一]。tap();
}
/ / --点击文本文件
uialogger。logMessage(“点击文本字段”);
VAR异常长的名字,recipename =“食谱”;
textfields() [窗口。0 ]。setValue(recipename);
目标。延迟(2);
/ / --点击文本文件
uialogger。logMessage(“把键盘”);
APP。logelementtree();
APP。keyboard()。buttons() [“回报”]。tap();
VaR textvalue =窗口“recipename。statictexts() [”];
调整避免你写同样的样板代码,加给你一些额外的喜欢各种说法:asserttrue(表达信息)
,assertmatch(正则表达式,表达式,消息)
,assertEquals(预期,收到的消息)
,assertfalse(表达信息)
,assertnull(东西、消息)
,assertnotnull(东西、消息)
…你可以延长图书馆很容易:例如,你可以添加一个logdevice
在uiautomation-ext.js添加此功能uiatarget对象的方法:
扩展(uiatarget.prototype,{
logdevice:function() {
uialogger。logMessage(“转储设备:”);
uialogger。logMessage(”模式:“+ uiatarget。localtarget()。model());
uialogger。logMessage(“矩形:“+ JSON。stringify(uiatarget。localtarget()。rect()));
uialogger。logMessage(“名称:”+ uiatarget。localtarget()。());
uialogger。logMessage(”系统:“+ uiatarget。localtarget()。systemname());
uialogger。logMessage(“systemversion:“+ uiatarget。localtarget()。systemversion());
;
然后,调用logdevice()目标。
你应该看到:
自卸装置:
模型:iPhone模拟器
矩形:{“缘起”:{“X”:0、“Y”:0 },“大小”:{“宽度”:320,“高度”:480 } }
名称:iPhone
你还可以看到如何从另一个脚本参考,以#进口
指令。因此,创造倍数测试和链接都可以通过导入在一个单一的文件进行调用:
#进口“test1 .js”
#进口“test2。JS”
#进口”4. JS”
#进口“考试4. JS”
#进口”测试JS”
如果你想使你的脚本,你可以从命令行启动。事实上,我推荐使用这个选项,而不是使用工具的图形用户界面。仪器的用户界面是缓慢的,和测试保持运行,即使你已经达到了他们的结束。在命令行启动uiautomation测试是很快的,你的脚本将在测试结束时停止。
这取决于你的Xcode版本,命令行是稍微不同的。
在任何版本,推出一个脚本,你将需要你的UDID。
在Xcode >=4.3<4.5,在一个终端类型:
仪表
W your_ios_udid \
T”/应用/ Xcode。APP /内容/开发者/平台/ iPhoneOS。平台/开发商/图书馆/工具/插件/ automationinstrument。束/内容/资源/自动化。tracetemplate”
name_of_your_app \
E uiascript absolute_path_to_the_test_file
在Xcode > = 4.5,在终端类型:
仪表
W your_ios_udid \
T”/应用/应用/内容/应用Xcode。/仪器。应用/内容/插件/ automationinstrument。束/内容/资源/自动化。tracetemplate”
name_of_your_app \
E uiascript absolute_path_to_the_test_file
例如,在我的情况下(Xcode 4.3),线看起来像:
仪器a2de620d4fc33e91f1f2f8a8cb0841d2xxxxxxxx W T /应用/ xcode.app/contents/developer/platforms/iphoneos.platform/developer/library/instruments/plugins/automationinstrument.bundle/contents/resources/automation.tracetemplate自动化测试- E uiascript /用户/ JC /文件/ dev /自动化测试/自动化测试/ testui / test-2.js
如果你正在使用一个版本的Xcode下到4.3,你将需要的类型:
仪表
W your_ios_device_udid \
T”/开发商/平台/ iPhoneOS。平台/开发商/图书馆/工具/插件/ automationinstrument。束/内容/资源/自动化。tracetemplate”
自动化测试\
E uiascript /用户/ JC /文件/ dev /自动化测试/自动化测试/ testui / test-2.js
你会注意到Xcode的不同版本之间的唯一区别是就位automation.tracetemplate
。任何东西之前,要确保automation.tracetemplate
在你提供的路径存在。再次,调整将使你的生活简单,有一个脚本热身/ test_runner /运行
会照顾识别和正确运行该命令行。
命令行的工作也与模拟器。你需要知道在模拟文件系统应用程序的绝对路径。该模拟器的模拟在下列文件夹中的设备文件系统~ /图书馆/技术支持/ iPhone模拟器/ 5.1/
。在这个目录下,你会发现包含为每个安装在模拟器的应用程序沙盒应用程序目录。只是确定在模拟器上测试自动化程序型知识库:
仪器/应用/ xcode.app/contents/developer/platforms/iphoneos.platform/developer/library/instruments/plugins/automationinstrument.bundle/contents/resources/automation.tracetemplate”/用户/ JC /图书馆/技术支持/ iPhone模拟器/ 5.1 /应用/ c28ddc1b-810e-43bd-a0e7-c16a680d8e15 /自动化测试,应用“E uiascript /用户/ JC /文件/ dev /自动化测试/自动化测试/ testui / test-2.js
你也可以给一个应用程序,在砂箱模拟器:例如,让我们说你有一个詹金斯服务器应用程序自动建立。您当前的建设将在类似的定位/用户/ JC /詹金斯/工作/自动化测试/工作区/自动化测试/建设/ testautomation.app
。你能给/用户/ JC /詹金斯/工作/自动化测试/工作区/自动化测试/建设/ testautomation.app
作为输入仪器
和仪器
会做复制和模拟器沙盒安装应用程序的必要。
一个小的抓,别忘了关掉设备密码,否则你会看到这个痕迹:例外:设备遇到远程锁定:未能与束标识符的COM的发射过程。manbolo自动化测试”。
。是的,uiautomation还不知道你的密码!
在命令行上的最后一句话。如果你不精确的输出文件,日志会放在文件夹中,你输入的命令。你可以使用E uiaresultspath results_path
将该脚本的输出。你也可以使用l
期权给予暂停脚本:例如l 60000
将60年代终止当前脚本。
我没有成功推出多个脚本与命令行。用整个晚上链和启动你的脚本,所以你真的会测试你的应用程序“睡觉”。
而不是打字脚本,您可以记录的相互作用直接在设备或模拟器,在重放。做这个:
在写你的剧本,你会玩的时间,动画等。uiautomation具有多种功能得到元素,即使他们没有显示但最好的建议就是等待从这个额外的演示:
当事情不顺利时,添加uiatarget延迟(1);!
在自动化测试报警处理一直是困难的:你写你的脚本,启动您的测试套件,临睡前,和,在早上,你会发现你所有的测试已经毁了因为你已经收到意想不到的短信,阻断试验。嗯,uiautomation帮你处理。
通过在你的脚本中添加此代码,
;
return false;//使用默认处理程序
和返回false,你问uiautomation自动解聘UIAlertView,所以警报不会干扰你的测试。你的脚本将运行如果没有任何警报。但警报可以应用程序部分和测试流程,在某些情况下,你不想自动把它。这样做,你可以对警报的职称考试,点击一些按钮,返回true。返回真,你表明uiautomation这警报应作为测试的一部分,处理一致。
例如,如果你想测试的添加一些“警报视图包上的“添加”按钮,你可以写:
;
如果(标题= =“增添”){
警报。buttons() [“添加”]。tap();
返回true;/ /旁路默认处理程序
}
return false;//使用默认处理程序
方便宝宝!
测试你的应用程序的多任务也很简单:让我们说你想测试那个疯狂的背景过程你发射每次应用程序恢复从背景和进入-(void)applicationwillenterforeground:(UIApplication *)中的应用
选择器,你可以在后台发送程序,等待10秒,并恢复它通过调用:
uiatarget。localtarget() deactivateappforduration(10);
deactivateappforduration(持续时间)
将暂停脚本,模拟用户点击主页按钮,(在后台发送应用程序),等待,恢复应用程序和测试脚本对你的简历,在一行代码!。
你可以模拟你的iPhone的旋转。再次,非常简单和容易的:
VaR目标= uiatarget。localtarget();
VaR应用为目标。frontmostapp();
/集景观左
目标。setdeviceorientation(uia_device_orientation_landscapeleft);
uialogger。logMessage(“目前的定位是“+应用程序。interfaceorientation());
/肖像
目标。setdeviceorientation(uia_device_orientation_portrait);
uialogger logMessage(。“目前的定位;
你可以很容易地把你的应用程序的当前状态截图。它可以针对一些有用的参考图像。
VaR目标= uiatarget。localtarget();
目标。capturescreenwithname(“screenshot1。png”;
该截图的位置将由路径你增加选项推断E uiaresultspath results_path
最后,您可以启动任何脚本(不仅JavaScript
这是在你的本地主机)。结合采取截图的能力,你可以想象强大的自动测试。你可以使用performtaskwithpathargumentstimeout(路径参数,超时)
与路径
包含脚本的完整路径,args
参数数组传递给你的脚本,和超时
一个…超时!
VaR目标= uiatarget。localtarget();
VAR主机=目标。host();
VaR结果=主机。performtaskwithpathargumentstimeout(“/usr/bin/vi回声”,[“Hello World”];
这是一个相当长的职位,但我希望你看到uiautomation功率和质量的潜在爆发,你的应用程序可以获得。没有很多的文档uiautomation,但我列出了一堆的链接,可以帮助你。
和,当然
你需要一个免费的开发者帐户访问该资源。
总结这趟uiautomation,我不住向你展示如何使用我们的uiautomation与激光在一个小的视频。我们使用各种测试,在这段视频中,我们测试,玩家可以从0级到120级的玩。救命我,我的iPhone是活着的!