设为首页 加入收藏

TOP

Xcode 7 中的 UI 测试功能(一)
2015-07-26 13:14:22 来源: 作者: 【 】 浏览:68
Tags:Xcode 测试 功能

苹果公司终于决定在今年的 WWDC 上对用户界面进行加倍测试,让我们深入到 API 看看我们能发现什么.


!Xcode Testing


我从事于 IOS 测试已经有几个年头了,在进入 BeerMenus 之前,我在 Pivotal 呆了两年,Pivots, 我们更愿意这样被称呼, 严谨测试.。作为测试驱动开发公司?(或者 TDD 公司), Pivots花时间来测试每一个角落裂缝。尽管代码的覆盖率并不是最优先级的,它们很容易包含95%,并不全是这样的项目。


Cedar


回到 Xcode 4,测试 iOS 应用的唯一方式就是 OCUnit,其遗留了许多有待改进之处。Pivots 利用了它们在?行为驱动开发(behavior-driven development)框架中的专业观点着手创建它们自己的测试套件?- ?Cedar?诞生了.


Cedar 是一个优秀的框架,用于创建 BDD 风格的测试,完全支持匹配器和伪装。而 Xcode 7 还没有完全的支持,Pivotal 在一个分支上跟进他们的工作,预计很快就会有东西要发布了。自从尝到 TDD 的甜头之后, 我使用 Cedar 测试过我所工作过的每一个 iOS 应用。我甚至开始把它用在功能测试控制器上,但那是下次的主题了。


单独使用 Cedar 不能给与我在使用 Ruby on Rails 时所日渐赞赏的端到端覆盖。我不能可靠地在几个屏幕之间进行触摸操作,让应用运作起来。可以理解的是,Cedar 并不用为那个而被创建出来的。为了填补这个空缺,许多玩家都已经创建了他们自己的第三方功能测试框架。


第三方测试


FrankKIFSubliminal, Apple 的 UIAutomation,我把他们都试了一遍。你要是希望了解更多可以访问我的故障特征测试框架。它不是开发者的失败,而是因为 Apple 对待测试只有有限的开放性。这使得这些框架有一系列的补丁,而在这些补丁之上,这些框架不外乎都成为了一堆破碎的工具。


没有涉及到的更多细节:


我在 Pivotal 工作的时候,有六个分离的 app,我尝试对每个不同应用使用不同的框架。我甚至对 KIFFrank 捐助,因为我希望这些框架成功。不幸地是,它们不可能离开 Apple 的支持。


WWDC 2015


WWDC


今年的 WWDC 带来了好消息:在各平台进展状态介绍环节对用户界面测试进行了介绍。


Wil Turner 和 Brooke Callahan 在第 406 节展示了新框架,Xcode 中的 UI 测试。如果你还没有看过它,建议去看一看。他们演示了一个简单的任务管理应用,对工具中的一些 API 和功能进行了高亮显示。


WWDC Demo


UI 测试的重头戏是“记录”。在你有了一个要位置工作的应用程序之后,点击一个大红圈,然后开始在你的 app 里面到处点击。当你正在与 app 交互时,代码会被自动生成出来以重现你的操作流程。理论上,之后你就能够运行新创建的测试,并看着 app 重复你之前的动作。


UI 测试实战


自卖自夸是一回事,在真实世界中这个框架会起作用吗?


文档


XCTest documentation in Dash


关于这个新框架你可能知道的首要事情之一就是文档的缺乏. ?iOS 9 和 Xcode 7 都没有包含 UI 测试的任何官方的文档。幸运的是,新的 XCU* 类中的大多数都拥有良好的注释的头文件。借助于?appledoc,我可以把这些头文件拖入 Xcode 兼容?Dash?的文件集合中。只要把资源库 clone 下来,将文件打开;默认的文档浏览器就会添加这些新的 API。你还可以在线查看文档


UI 测试位于 XCTest 框架,添加了4个新的类,1个新的协议,以及3个新的常量。


这是用来启动你要测试的应用程序的主要拉钩。你可创建一个新的实例,[[XCUIApplication alloc] init], 然后在它上面调用 -launch。 如果你向应用添加了一个新的 UI 测试目标,就会在模板里面看见一个示例。在启动之前,你可以通过设置 -launchArguments?或者?-launchEnvironment ?属性来分别设定一个特殊的参数或者环境变量。这样会创建一个漂亮的布局,例如,向你的 HTTP 客户端告知,在测试时访问一个模拟的服务器.


XCUIApplication *app = [[XCUIApplication alloc] init];
app.launchArguments = @[ @"USE_MOCK_SERVER" ];
[app launch];


你还可以 -terminate 你的 app,但我还没有发现过对那个东西的使用。


你可以使用 +sharedDevice 创建这个对象的一个新实例。唯一可以被公共的访问到的属性是-orientation,它会返回普通的 UIDeviceOrientation 枚举值。虽然这是一个可读可写的属性,但是对他进行了设置并不会对模拟器的界面进行更新。我不确定这是不是我正在使用的 beta 版的一个 bug。


这将是 UI 测试中使用率最高的一类,因它可用来构建查询以定位元素。还记得 UI 自动化里的 app.tableViews[0].cells[0] 吗?二者极其相似。


[[app.tables.element.cells elementAtIndex:4] tap];


每次调用堆栈都会返回一个可被链接在一起的查询对象,这就让控制应用程序变得更加精确。提到-element(元素),你便会说“我知道这儿只有一个,我要的就是这个”。你还可以通过特定的标签来访问堆栈中的对象。


[app.tables.element.cells[@"Call Mom"].buttons[@"More"] tap];


这种便捷的方式将通过 -elementMatchingType:identifier: 和 XCUIElementTypeAny,以及你传递的字符串来实现。如果想要更精确地控制所有选择,通过元素查询 XCUIElementType 将是最佳的方式。


?


?


?


创建一个 XCUIElementQuery 的方式,会给予你元素的引用。除非你真的到了要与其交互的时候,框架是不会实际去应用的层级中找寻它们的。 这样为你带来了保持干净的测试的好处——你可以保留一个查询的引用,在测试的不同地方重用它。元素只会在交互期间才会被查找,这样就为你节省了再一次深入获取的花费。


?


交互都被进行了恰当的命名,会像你所期望的那样执行动作。例如,在 iOS 中你可以使用 -tap, -pressForDuration:, -swipeUp, 以及 -twoFingerTap。 如果你测试的是一个 OS X 应用,你可以对应地使用-click* 交互. 你甚至还可以使用 +performWithKeyModifiers:block: 来模拟持续的按下 ? 按键.


一个测试框架里怎么可能没有断言?由于 UI 测试只是 XCTest 的扩展,所有已有的断言仍然管用,你仍然可以使用像 XCTAssert(),XCTAssertEquals(),和 XCTAssertNotNil() 这样的断言宏。


检查某个元素是否存在


一个快速的方法就是在一个元素对象上进行非空断言测试:


XCTAssertNotNil(app.buttons[@"Submit"]);


但是,elementMatchingType:identifier:总是返回一个对象,在这这个函数解析完之前,由它来决定了一个元素是否真的与查询相匹配,这说明这个测??总是通过的。作为替代,在断言中通过在元素上调用 -exist 方法来包装一下,像这样:


XCTAssert(app.buttons[@"Submit"].exists);

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
分享到: 
上一篇PHP 安全编程建议 下一篇设计模式学习之——命令模式

评论

帐  号: 密码: (新用户注册)
验 证 码:
表  情:
内  容: