测试|博客 iOS 自动化测试常用语句


转自http://www.devdiv.com/ios_-blog-312313-50772.html

// tableview向下滑动一个屏幕的内容 上下左右
target.frontMostApp().mainWindow().tableViews()[1].scrollDown();
target.frontMostApp().mainWindow().tableViews()[1].scrollUp();
target.frontMostApp().mainWindow().tableViews()[1].scrollLeft();
target.frontMostApp().mainWindow().tableViews()[1].scrollRight();


// tableview按照指定坐标滑动,x,y轴均可设定
target.flickFromTo({x:100,y:400},{x:100,y:20});


// 持续向下滑动,tableView和scrollView都可以使用
for (var j = 0; j < 5; j++) {
target.flickFromTo({x:100,y:400},{x:100,y:20});
}


// 可见cell的数组里面的第几个
target.frontMostApp().mainWindow().tableViews()[1].visibleCells()[0].tap();


// 实际的cell第几个
target.frontMostApp().mainWindow().tableViews()[1].cells()[0].tap();


// scrollView 上下左右滑动一真个屏幕
target.frontMostApp().mainWindow().scrollViews()[0].scrollUp();
target.frontMostApp().mainWindow().scrollViews()[0].scrollDown();
target.frontMostApp().mainWindow().scrollViews()[0].scrollLeft();
target.frontMostApp().mainWindow().scrollViews()[0].scrollRight();


// button 设置下面的属性后,自动测试时可以读取到响应的button
deleteButton.accessibilityLabel =@"press";

// 延时语句
UIATarget.localTarget().delay(3);


// 支持循环语句 和 if语句
for (var i = 0; i < 5; i++) {
}
if (i == 0) {
}




iOS开发: UI自动化测试

一.UI自动化测试概述
通过编写自动化测试脚本,并结合instrument工具,来自动化测试你的程序UI,进而大大节省测试人员的时间和精力。这些脚本是苹果自iOS4.0提供给开发者的JavaScript编程接口,这些接口一一对应着用户与iOS程序的交互行为,如按钮点击,文本输入,表格滑动等等。在测试过程中,系统会打印出相应的测试日志来方便开发者调试定位程序。
该自动化测试框架提供了以下的主要功能:
l访问你的UI元素的层级关系
l提供定时器的支持
l提供强大的日志功能
l提供对UIAlertView的处理机制
l支持对设备转向的处理
l拥有对多任务的处理机制
注意:
1.当你在设备上运行自动化测试脚本时,该测试脚本不会阻止设备自动锁定,因此切记在测试前,请关闭设备的自动锁定功能

二.运行你的第一个自动化测试脚本
1.使用模拟器
1)确保目标模拟器选择为4.0以上(注意:如果是自己录制操作而不是直接编写或导入js脚本, 则必须选择5.0以上的模拟器,因为录制功能只支持5.0以上版本)

2)启动Instruments (Product > Profile) 或者快捷键?I
3)在iOS模拟器面板中选择Automation模版,然后点击Profile


4)Instruments运行并立即开始录制,此时暂且停止录制(点击红色按钮或者快捷键?R)

5) 在脚本子窗口点击’Add > Create’创建一个新脚本

6)在脚本编辑窗口,敲入下面的代码
var target =UIATarget.localTarget();
var app =target.frontMostApp();
var window =app.mainWindow();
target.logElementTree();

7)再次点击红色按钮或者?R(脚本写完后不需要保存)。脚本开始运行,等日志运行结束且日志全都打印完毕后,你可以停止录制(同样的点击红色按钮)


至此,你的第一个在模拟器中运行的自动化测试脚本编写完成了。

2.使用真机
1)连接你的设备到电脑
2)选择你的scheme为‘iOS Device’3)点击“Product->Profile”或者?I,运行测试脚本
三.详解UI自动化测试

1.UIAElement层级关系简介
每一个可被自动化测试框架访问到的UIKit控件都对应着一个Javascript对象:UIAElement。我们自动化测试中测试脚本的编写,正是通过操作一系列的UIAElement子类完成的。这些子类对应到UIKit框架中的每一个标准控件。UIAElement包含多个属性,name, value, elements, parent。你可以通过设置name属性来给你的UI控件起一个名字,value为UI元素的值,如文本框的文本值,elements为该UI元素的所有子元素,parent为它的父元素。你的程序的UI层级关系对应着一个UIAElement层级关系,见下图所示:



自动化测试框架和UI元素的Accessibility可访问性密切相关,要想改变你的某一个UI元素的可访问性,可以通过改变UI控件的isAccessibilityElement属性值来完成,设为YES表示可被用于自动化测试,设为NO则不能用于自动化测试。UIKit中的所有标准系统控件的该属性值默认都为YES,即只要我们程序中的UI元素是继承自UIKit中的系统控件,则默认都是可被自动化测试框架访问到的,因此我们不用手动改变该值。

2.理解UIAElement层级关系
lUIAElement层级的最顶层是UIATarget类,相当于你的设备或模拟器,该类具有管理和访问你的设备相关信息的基本功能。要想获得你的target,你可以使用以下的代码:
var target = UIATarget.localTarget();
l获得你的application,对应于UIApplication:
var app= target.frontMostApp();
l获得你的主窗口,对应于UIWindow:
var window = app.mainWindow();
l下面用以下界面做例子,讲解基本的界面元素访问方法:

1)获得图中所示的表格视图UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0];
2)获得表格的第一行cellUIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[0];
3)获得第一行cell中的标题label
UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells()[0].elements()["ChocolateCake"];

l你可以通过索引值或者名称标识获得想要的某一个UI元素:
【测试|博客 iOS 自动化测试常用语句】var textField =UIATarget.localTarget().frontMostApp().mainWindow().textFields()[0]; //取得window中第一个textfield,注意:顺序的判定是依据“从上到下,从左到右”的原则确定的

vartextField =UIATarget.localTarget().frontMostApp().mainWindow().textFields()["User Text"]; //取得window中name为“User Text”的textfield
l每一个UIAElement可以通过调用以下的函数来访问它的子元素:buttons(), images(),scrollViews(),textFields(),webViews(),segmentedControls(), sliders(),staticTexts(),switches(),tabBar(), tableViews(), textViews(), toolbar(),toolbars()等等。
例如,为了访问tabbar中的第一个tab,可以这样:
var tabBar =UIATarget.localTarget().frontMostApp().tabBar();
vartabButton = tabBar.buttons()["First"];
3. 打印UIAElement层级关系
你可以使用任意UI控件的logElementTree方法打印出它的所有子元素:
UIATarget.localTarget().logElementTree();
上图的element层级关系,打印如下:

4. 模拟用户动作
l单击操作
UIATarget.localTarget().frontMostApp().navigationBar().buttons()["Add"].tap();
l对于较复杂的程序,可以精确点击,即确定点击的位置坐标
UIATarget.localTarget().tap({x:100,y:200});
l其他一些动作
a)单指双击
UIATarget.localTarget().doubleTap({x:100,y:200});
b)双指单击
UIATarget.localTarget().twoFingerTap({x:100,y:200});
C)Pinch动作
UIATarget.localTarget().pinchOpenFromToForDuration({x:20,y:200}, {x:300, y:200}, 2);
UIATarget.localTarget().pinchCloseFromToForDuration({x:20,y:200}, {x:300, y:200}, 2);
d)拖拽动作
UIATarget.localTarget().dragFromToForDuration({x:160,y:200}, {x:160, y:400}, 1);
l输入文本
varrecipeName = "Unusually Long Name for a Recipe";
UIATarget.localTarget().frontMostApp().mainWindow().textFields()[0].setValue(recipeName);
l滚动到指定元素(有三个常用方法:scrollToElementWithName,scrollToElementWithValueForKey,scrollToElementWithPredicate)
UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].scrollToElementWithPredicate("namebeginswith ‘Turtle Pie’");
5. 支持超时访问控制功能
对于某些场景,界面上的某一元素可能需要一段加载时间才能显示出来,你可能希望某一界面元素在合理的等待时间内展示出来,对于超过了你所规定的时间仍然未显示,则说明可能存在问题。UIAutomation自动话测试框架提供了该功能的支持,在你所指定的时间间隔内,框架会不断的尝试访问你所要求访问的UI元素,直到成功访问到,才继续往下执行;若在超时范围内仍然尝试不成功,则会抛出异常,具体如下:
UIATarget.localTarget().pushTimeout(2); //2秒的超时时间
//此处添加你所希望访问的界面元素
UIATarget.localTarget().popTimeout();
6. 支持延迟操作,即延迟一段时间再继续执行测试脚本
UIATarget.localTarget().delay(2);
四.简洁实用的日志功能
自动化测试脚本会收集打印出测试的详细日志,以便于开发者测试分析程序的行为。当你在编写测试脚本时,你应该打印出适量的日志,以便于你的测试分析工作。
1. 至少,你应该在每一次脚本运行的开始和结束打上日志(logStart,logEnd),在脚本测试成功或失败时打上日志(logPass,logFail),示例如下:
vartestName = "Module 001 Test";
UIALogger.logStart(testName);
//你的测试代码
UIALogger.logPass(testName);
2. 打印普通信息时,可以使用logMessage,如下:
UIALogger.logMessage("Test1 finished!Test 2 isbeginning……");
3. 打印警告信息时,使用logWarning,示例如下:
UIALogger.logWarning("Test1 has some problem!");
4. 为了避免纯文本日志的枯燥无味,UIAutomation框架为我们提供了测试过程中的截图功能,可以将你所想要的任意画面甚至是任意指定某一范围的区域截取成图片,并最终输出到日志中去,示例如下:
vartestName = " Test 1";
UIALogger.logStart(testName);
//一些测试代码
UIALogger.logMessage("Startingtest for login……");
//截屏
UIATarget.localTarget().captureScreenWithName("img1_Login");
//一些测试代码
UIALogger.logPass(testName);
注意:截屏功能只支持真机,若在模拟器中尝试,则会在日志中打印出尝试截屏出错的提示信息
5. 校验测试结果
对于某个测试结果,你可以校验它的有效性,例如,你可能寄希望于当前界面会出现某个UI元素,如表格中的某一行的标题会出现 “Weekend”开头的字样,你可以使用如下方法:
var cell =UIATarget.localTarget().frontMostApp().mainWindow().tableViews()[0].cells().firstWithPredicate("namebeginswith ‘Weekend’");
if (cell.isValid()) {
UIALogger.logPass(testName);
}
else {
UIALogger.logFail(testName);
}

五.处理AlertView警告框
在我们的UI测试过程中,我们需要恰当的处理程序中各种alert弹出的情况;除此之外,我们也无法避免来自程序外部的alert的弹出,比如在测试过程中,收到短信,电话,系统通知之类的alert;

1. 处理程序外部的alert
下面的示例简单的打印出外部的alert的标题,紧接着关闭alert,如下所示:
UIATarget.onAlert = function onAlert(alert) {
var title = alert.name();
UIALogger.logWarning("Alert with title'" + title + "'encountered.");
// return false to use the default handler
return false;
}
此处说明一下:
1.以上示例中的onAlert为UIATarget的一个方法,当在你的自动化测试过程中,弹出一个alert视图,自动化测试框架会自动调用该方法,该方法的默认实现是:若发现该alert有cancel按钮,则首先尝试点击一下cancel按钮,若只有一个默认按钮,则紧接着尝试点击一下该按钮,若经过两次点击,仍然无法关闭该alert,则框架会抛出异常,脚本结束运行。
2. 如果你想要提供自己的alert的处理方法,可以仿照上面的代码,这里最关键的代码是最后一行的“return false“; 返回false则代表接下来让框架接手处理alert:即第一条所述的onAlert的默认实现方式,尝试关闭alert。
3. 注意:若遇到一下子连续有多个alert蹦出来而达到了alert上限,则onAlert方法的默认实现会停止关闭alert,此时需要我们自己来处理了

2. 处理程序自身的alert
处理程序自身的alert方法类似,下面简单举一个例子:
UIATarget.onAlert= function onAlert(alert) {
vartitle = alert.name();
UIALogger.logWarning("Alertwith title '" + title + "'encountered.");
if(title == "The Alert We Expected") {
alert.buttons()["Continue"].tap();
returntrue; //标志alert程序已经处理完毕,不需要系统处理了
}
//return false代表接下来需要系统来尝试关闭alert
returnfalse;
}

六.处理设备转向问题
UIAutomation支持对设备转向的处理,你可以在脚本中方便的随时改变设备的方向,下面举一个简单的例子:
vartarget = UIATarget.localTarget();
varapp = target.frontMostApp();
//setorientation to landscape left
target.setDeviceOrientation(UIA_DEVICE_ORIENTATION_LANDSCAPELEFT);
UIALogger.logMessage("Currentorientation now " +app.interfaceOrientation());
//resetorientation to portrait
target.setDeviceOrientation(UIA_DEVICE_ORIENTATION_PORTRAIT);
UIALogger.logMessage("Currentorientation now " +app.interfaceOrientation());

七.多任务的支持
自iOS4.0以后,iOS系统引入多任务支持,UIAutomation自动化测试框架也同时支持多任务。框架可以模拟用户的点击home键,或是锁定设备,再切换回程序的行为,通过调用以下的方法实现该机制:
//模拟用户点击home键,然后等待10秒钟又返回到程序的行为
UIATarget.localTarget().deactivateAppForDuration(10);

八.补充说明
1. 对于键盘消失的方法,可以使用以下语句:
app.keyboard().buttons()["return"].tap();
若上述方法无效,请使用以下方法:
app.keyboard().buttons()["\0"].tap();
2. 对于自动化测试的脚本编写,比较耗费时间和精力,针对iOS5.0以上,可以使用录制功能,录制完基本交互动作后,你再在自动生成的脚本中补充加入你自己想要的功能,借此可以大幅提高测试效率。步骤如下:
1)启动Instruments
2)Create一个新的脚本
3)选择脚本编辑器

4)在脚本编辑器的下方你会看到一个红色按钮,那便是录制按钮

3. 小技巧:UIATarget.delay(1);
在脚本运行过程中,若发现某行脚本不能运行,则可能是因为脚本执行速度过快,iOS界面渲染慢,导致无法成功执行脚本,如某个按钮还没准备好和用户交互,此时脚本触发tap()操作,显然会导致失败
4. 在脚本编写过程中,我们很容易会发现,许多同样的脚本代码经常在各处都要用到,造成我们大量重复编写。国外大牛们提供了一个第三方开源小框架,该框架把我们平时经常会重复用到的脚本都整合到了一起,我们只需#import"tuneup/tuneup.js" 导入该js框架,然后直接调用它封好的方法即可,省时省力。
该框架还为我们提供了断言机制,如判断一个语句的正确性,判断两个语句的是否相等,判断某个对象是否为空等等,常用的断言如下:assertTrue(expression, message),
assertEquals(expected,received, message),assertNull(thingie, message)
5. 在脚本编写过程中,你可能需要将多个小的脚本链接成一个单个文件,或者说你想在某个脚本中用到另外一个脚本,则可以使用#import命令,将需要的脚本导入,如下所示:
#import"Test1.js"
#import"Test2.js"
#import"Test3.js"

九.参考资料
1. 苹果官方的开发文档
http://developer.apple.com/library/ios/#documentation/DeveloperTools/Conceptual/InstrumentsUserGuide/UsingtheAutomationInstrument/UsingtheAutomationInstrument.html%23//apple_ref/doc/uid/TP40004652-CH20-SW1
2. 国外技术牛人写的教程
http://blog.manbolo.com/2012/04/08/ios-automated-tests-with-uiautomation#1
3. 另外附上我们后续编写测试脚本时会一直要用到的api接口文档,由于涉及到接口较多,请大家自行查阅文档
file:///Applications/Xcode.app/Contents/Developer/Platforms/iPhoneOS.platform/Developer/Documentation/DocSets/com.apple.adc.documentation.AppleiOS6.0.iOSLibrary.docset/Contents/Resources/Documents/index.html#documentation/DeveloperTools/Reference/UIAutomationRef/_index.html#//apple_ref/doc/uid/TP40009771

    推荐阅读