转自:http://www.cnblogs.com/vowei/archive/2012/08/10/2631949.html

写在前面

研究iOS的自动化测试也有些日子了,刚开始的时候,一直苦于找不到什么好的资料,只能从Apple的官网查阅相关的API文档,只可惜,Apple对开发者来说实在是不怎么友好,文档写得相当的粗略,对于初学者来说有一定的难度。

本来是打算自己动手写一篇关于iOS的UI自动化测试的入门级别的介绍性文档的,但想起来后面在具体解决一些问题的时候,收藏一篇很好的Blog,很全面地介绍了如何使用UIAutomation的JavaScript Libraries做iOS程序的自动化测试。如果作者早点看到这篇文章,应该要少走一些弯路,这里没有创意性的它他翻译成中文,希望对你们有一些帮助。

原文地址:http://blog.manbolo.com/2012/04/08/ios-automated-tests-with-uiautomation

翻译正文:

快速入门

自动化测试代码可以“在你的睡着的时候”很好地帮你测试你的应用程序。它可以让你能够快速地跟踪你程序中的回归和性能方面的问题,这样你就不用担心你新增的功能会影响到你之前已经完成开发的程序了。

随着iOS4.0的发布,苹果公司同时发布了一个名为UIAutomation的测试框架,它可以用来在真实设备和iPhone模拟器上执行自动化测试。但官方关于UIAutomation的文档相当的有限,在网络上也没有太多的资源可以查找的。本文将向你展示你如何将UIAutomation整合到你的工作流程当中去。

作为基础知识的准备,你可以先看一下苹果公司关于UIAutomation的文档,另外还有一篇快速入门的介绍苹果Instruments的文档也值得看看,当然,如果你有一个免费的Apple开发者账号的话,你可以看一下WWDC 2010 - Session 306 – 使用Instruments进行用户界面自动化测试的幻灯片或者视频。

除此之外,包括在Xcode中的OCUnit测试框架也可以用来为你的应用程序编写单元测试。

1. 第一个UIAutomation测试脚本

  • 使用iOS 模拟器
  • 使用iOS设备

2. 处理UIAElement和元素可访问性(Accessibility)

  • UIAElement层次结构
  • 模拟用户操作

3. 经验分享(让你的生活变得更简单)

  • 类库Tune-up介绍
  • 导入外部脚本
  • 使用强大的命令行
  • 使用录制交互功能
  • 当遇到问题时,加上“UIATarget.delay(1);”

4. 高级交互

  • 处理非预期和预期的提示框(alerts)
  • 多任务
  • 屏幕方向

5. 总结

  • 有用的链接
  • 一个视频

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. 在脚本编辑器里,输入下面的代码

1
2
3
4
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}}

你可以通过下面的代码来访问文本框:

1
2
var textField =
UIATarget.localTarget().frontMostApp().mainWindow().textFields()[0];

你可以选择通过从0开始的索引或者这个元素的名称来访问这个元素,例如:你也可以通过下面的代码来访问文本控件。

1
2
var textField =
UIATarget.localTarget().frontMostApp().mainWindow().textFields()["User Text"];

后一种方式更加清晰明了,应该多使用。你可以通过Interface Builder设置UIAElement的name属性,

或者通过编写代码的方式:

1
2
myTextField.accessibilityEnabled = YES;
myTextField.accessibilityLabel = @"User Text";

你现在可以看到,通过accessibility属性可以被UIAutomation用来找到不同的控件。这非常的清晰,因为,第一,你只要学习一个测试框架;第二,通过编写自动化测试代码,你同时还可以保证你的程序是可以被访问的。因此,每一个UIAElement对象的子控件可以通过下面的方法进行访问:

buttons(), images(), scrollViews(),textFields(), webViews(), segmentedControls(), sliders(), staticTexts(), switches(), tabBar(),tableViews(), textViews(), toolbar(), toolbars() 等等……

你可以通过如下代码在tabbar上访问第一个tab:

1
2
var tabBar = UIATarget.localTarget().frontMostApp().tabBar();
var tabButton = tabBar.buttons()["First"];

UIAElement结构层次非常的重要,你以后会常常用到它。而且你还要记住,你可以在随时通过调用UIAAplication的logElementTree来获得它的结构。

1
UIATarget.localTarget().frontMostApp().logElementTree();

在模拟器上,你还可以激活Accessibility 的检测器。启动模拟器,找到“Settings > General > Accessibility > Accessibility Inspector”,然后将它设为“打开”状态。

这个彩色的小框框就是Accessibility 检测器了。当它收起来的时候,Accessibility就被关闭了,当它展开的时候,Accessibility就是打开的。你只要点击上面的箭头按钮就可以激活或者屏蔽Accessibility。现在,打开我们的示例程序,激活检测器。

然后,点击文本框,检查UIAElement的name和value属性(其实就是accessibilityLabel和accessibilityValue对应的NSObject类型的值)。这个检测器可以帮助你调试和编写你的测试代码。

模拟用户操作

让我们更进一步,模拟一些用户的交互操作。你可以简单地调用按钮的tap()来作一个点击操作:

1
2
3
4
5
var tabBar = UIATarget.localTarget().frontMostApp().tabBar();
var tabButton = tabBar.buttons()["First"];  
 
// Tap the tab bar !
tabButton.tap();

你还可以调用UIAButtons的doubleTap(), twoFingerTap()。如果你不想操作具体的某个元素,你也可以直接根据屏幕上指定的坐标点进行操作,你可以这么用:

  • 点击:
1
2
3
UIATarget.localTarget().tap({x:100, y:200});
UIATarget.localTarget().doubleTap({x:100, y:200});
UIATarget.localTarget().twoFingerTap({x:100, y:200});

  • 缩放:
1
2
UIATarget.localTarget().pinchOpenFromToForDuration({x:20, y:200},{x:300, y:200},2);
UIATarget.localTarget().pinchCloseFromToForDuration({x:20, y:200}, {x:300, y:200},2);

  • 拖拽与划动:
1
2
UIATarget.localTarget().dragFromToForDuration({x:160, y:200},{x:160,y:400},1);
UIATarget.localTarget().flickFromTo({x:160, y:200},{x:160, y:400});

注意,当你指定操作的时间间隔的时候,它是有特定的范围的,即:拖拽操作的时间间隔必须大于或者等于0.5秒,小于60秒。

现在,让我们来练习一下:

  1. 停止Instruments (⌘R)
  2. 在Scripts窗口里, 移除当前的脚本
  3. 点击“Add > Import”然后选择TestAutomation/TestUI/Test-1.js(将下面的代码保存到这个路径)
  4. 点击录制按钮 (⌘R) 然后看看将会发生什么…

下面是Test-1.js代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var testName = "Test 1";
var target = UIATarget.localTarget();
var app = target.frontMostApp();
var window = app.mainWindow();
UIALogger.logStart( testName );
app.logElementTree();
//-- select the elements
UIALogger.logMessage( "Select the first tab" );
var tabBar = app.tabBar();
var selectedTabName = tabBar.selectedButton().name();
if (selectedTabName != "First") {
    tabBar.buttons()["First"].tap();
}
//-- tap on the text fiels
UIALogger.logMessage( "Tap on the text field now" );
var recipeName = "Unusually Long Name for a Recipe";
window.textFields()[0].setValue(recipeName);
target.delay( 2 );
//-- tap on the text fiels
UIALogger.logMessage( "Dismiss the keyboard" );
app.logElementTree();
app.keyboard().buttons()["return"].tap();
var textValue = window.staticTexts()["RecipeName"].value();
if (textValue === recipeName){
    UIALogger.logPass( testName );
}
else{
    UIALogger.logFail( testName );
}

这段脚本先启动待测程序,然后,如果第一个tab没有被选的话就切换到第一个tab,并将上面的文本框的值设成“Unusually Long Name for a Recipe”,接着收起虚拟键盘。这里有一些新的方法值得注意的:UIATarget的delay(Number timeInterval) 方法允许你在两个操作之间做一些等待,UIALogger的logMessage( String message) 方法用来将你想打印的信息输出到日志上去,UIALogger的logPass(String message)方法指明你的测试脚本已经成功的完成测试了。

你还知道了如何访问键盘上的按钮,然后作点击操作:

1
app.keyboard().buttons()["return"].tap();

由于时间有限且原文太长,先只能翻译到这里,我会尽快的将剩下的部分翻译补上。另外,时间仓促,如有翻译得不准确的地方,也敬请担待。谢谢。

如何使用UIAutomation进行iOS 自动化测试(Part I)的更多相关文章

  1. iOS自动化测试的那些干货

    前言 如果有测试大佬发现内容不对,欢迎指正,我会及时修改. 大多数的iOS App(没有持续集成)迭代流程是这样的 也就是说,测试是发布之前的最后一道关卡.如果bug不能在测试中发现,那么bug就会抵 ...

  2. IOS自动化测试环境搭建(Python & Java)

         一.前言 IOS的App自动化测试与Android的一样,也可以用appium来进行.但是IOS自动化依赖苹果的osx系统.Xcode构建等,且封闭的系统需要苹果开发者账号才可以驱动真机.A ...

  3. 零成本实现Android/iOS自动化测试:基于Appium和Test Perfect

    https://item.taobao.com/item.htm?spm=a230r.1.14.14.42KJ3L&id=527677900735&ns=1&abbucket= ...

  4. mac上搭建appium+IOS自动化测试环境(一)

    阅读须知 由于OS X系统最近才开始接触,所以有些东西也不是很清楚,这里只提供方法不提供原理,能解释清楚的我也会尽量解释.可能也有一些地方说的不严谨或有错的,还望大家指点一二. 实验环境 操作系统: ...

  5. InstrumentDriver,对iOS自动化测试说 Yes!

    InstrumentDriver 是 Mobile自动化小组最近实现的基于 instrument,针对 iOS 的自动化测试框架,目前支持 java 语言编写测试用例. 研究过iOS自动化测试的同学肯 ...

  6. mac上搭建appium+IOS自动化测试环境(二)

    上一篇: mac上搭建appium+IOS自动化测试环境(一) 9.安装appium-xcuitest-driver依赖 进入WebDriverAgent安装目录,运行bootstrap 首先进入目录 ...

  7. appium ios 自动化测试

    iOS自动化测试:Appium 从入门到实践https://www.jianshu.com/p/43f858180557appium自动化测试iOS Demohttps://www.jianshu.c ...

  8. 【Mac + Appium + Python3.6学习(四)】之常用的IOS自动化测试API总结

    环境: Appium:1.9.1 Appium-desktop:1.7.1 Xcode:10.0 IOS:iPhone5S(10.3.3) Mac:10.13.6 ①获取手机屏幕size:长.宽 &l ...

  9. 【Mac + Appium + Python3.6学习(三)】之IOS自动化测试环境配置

    在做这一节之前先配置我的另一篇文章所需要安装的前提准备条件:<[Mac + Appium学习(一)]之安装Appium环境前提准备> 一.安装IOS自动化测试环境 配置环境: Appium ...

随机推荐

  1. 初涉Node.js

    Node.js的是建立在Chrome的JavaScript的运行时,可方便地构建快速,可扩展的网络应用程序的平台. Node.js使用事件驱动.非阻塞I/ O模型,是轻量级.高效.完美的跨分布式设备运 ...

  2. ADT通过svn进行团队开发,svn插件不好使的解决方案

    在使用ADT的svn插件的时候老是会出现各种异常,所以就干脆不用svn插件了,直接将adt的工作空间建在svn上面,以保证团队成员共用一套代码,节约宝贵的整合时间. 使用步骤: 1.首先需要安装好sv ...

  3. 在云服务器搭建WordPress博客(五)创建和管理文章分类

    不同主题的文章划分到不同的分类,有助于访客寻找他们想要的内容,提高用户体验.所以,为你的网站创建文章分类是很有必要的.那么,WordPress系统如何创建和管理文章分类呢?今天倡萌就简单介绍一下. 创 ...

  4. BAT CMD 批处理文件脚本 -1

    http://www.cnblogs.com/linglizeng/archive/2010/01/29/Bat-CMD-ChineseVerion.html 1.               综述 ...

  5. ETL Pentaho Data Integration (Kettle) 插入/更新 问题 etl

    Pentaho Data Integration (Kettle) 使用此工具 按 索引  做 插入更新操作时,也可能报 索引重复 的错误, 解决方法:  匹配的索引字段可能有null值,会导致此错误 ...

  6. select模式

    在很多比较各种网络模型的文章中,但凡提到select模型时,都会说select受限于轮询的套接字数量,这个 数量也就是系统头文件中定义的FD_SETSIZE值(例如64).但事实上这个算不上真的限制. ...

  7. windows server 2008 R2 远程连接用户数修改

    设置windows server 2008 R2 远程连接用户数修改,三步搞定 1.运行(win+R)中输入tsconfig.msc 2.双击“限制每个用户只能进行一个会话”,取消这个选项负选框 3. ...

  8. Unity3D 相关项目代码

    一.Application.PresistentDataPath 注意最后面是没有/的 public static string PresistentDataPathForEditor = " ...

  9. .NET基础篇——Entity Framework 数据转换层通用类

    在实现基础的三层开发的时候,大家时常会在数据层对每个实体进行CRUD的操作,其中存在相当多的重复代码.为了减少重复代码的出现,通常都会定义一个共用类,实现相似的操作,下面为大家介绍一下Entity F ...

  10. iframe标签用法详解(属性、透明、自适应高度)(总结)

    <iframe src="http://www.jb51.net" width="200" height="500"> 脚本之家 ...