本文翻译来源于:http://www.mokacoding.com/blog/xcode-7-ui-testing/ ,如有不妥之处请联系我进行删除,承诺本文不会用于商业用途。
注:以下代码都是基于 Xcode 7 Beta 1 和 Swift 2.0。我尽可能使用最新版本来实践,如果我有遗漏的地方,请在底部留言。
WWDC 2015 或许没给我们带来太大的惊喜,但它还是给我们带来一些非常棒的消息。我在另外篇文章 2015 iOS 的测试前景 中写道:
尽管 iOS、OS X 的单元测试在过去两年中变得越来越好,但其它可验收性的测试(UI 测试)却没有得到什么改善。
好了,可验收性测试(UI 测试)这种不利的情况在 Xcode 7 上得到很好的改善,而且变得更好。
Xcode Beta 7 增加了 “UI Testing Bundle”,通过它我们就可以写和运行可验收性(UI 测试)的测试了。
需要注意的是曾经风靡一时的 UIAutomation 已经被苹果官方移除,尽管它依然存活在 Instruments 里,但我们不在需要用到它了,我们将使用新的 API 写 UI 测试。
这些新的 API 对 Swift 和 XCTest 插件的支持非常友好,我们只需要一个简单的快捷键 ⌘U
即可运行已写好的 UI 测试。
新的测试跟我们以前写的原理差不多,例如我们使用 KIF,Calabash,Appium 等等写的一样,它能像人为一样操作 app,这得益于 iOS Accessibility 的交互协议,这些在 iOS 9 上都得到很大的提升。
开启 Xcode 7 UI 测试之旅
在开始尝试之前,我们要意识到尝鲜的代价,可能会有很多坑等着你来踩,所以我提醒你项目一定要使用 Xcode 7 和基于 iOS 9 进行开发。
在这篇文章中,我们会重写以前使用第三方 UI 测试架构写过的一个项目 Bench。如果你想了解更多如何写 UI 测试的话,可以查看这两篇 文章 。
在 Bench 项目中,首先需要新增一个 target,你会在 Xcode 7 上看到一个专门的测试项。
选择 UI Testing Bundle
,这个支持 Object-C 和 Swift,我觉得最好使用 Swift 来写新的 API,如果你还没有,那么现在来尝试吧。
在生成的样板代码中还不能为我们做什么,它建议使用录制功能来生成 UI 测试代码。
Xcode 7 提供了 “录制” 这一有趣的功能,它能帮助我们生成大部分的 UI 测试代码。只需点击左下角的录制按钮,将游标移进任何一个 test....()
方法后,开始进行 App 的交互,即可看到 UI 测试代码如魔法般生成。
我们为 Bench 项目设定的第一个验收标准是:当我点击 “say hello” 按钮时,会看到一个弹出框。
此交互所生成的代码如下:
1 | testSayHello() { |
正如你所看到的语法是非常简单的,当我们运行测试时,在控制台会看到如下信息:
1 | Test Case '-[BenchUITests.BenchUITests testSayHello]' started. |
这些输出信息记录了从开始测试到各种动作和花费的时间,这些对我们检查 app 的问题起到很大的作用,就像检测鸡蛋一样。
你也可以这样看测试报告,当你点击 inspector 按钮时会看到如下图一样的 app 测试失败状态页面。
你也许也注意到这测试跟人进行的测试没有什么不同之处。
App 状态的断言
Bench 的第二个测试标准是:当点击 “show elements” 按钮,会看到一个列表元素。
这个测试通过录制生成的代码如下:
1 | func testShowElements() { |
这些对我们非常没有帮助,只是相当于列出一些简单的单元内容而已。
我们可以改这个 UI 测试为单纯的检验在屏幕上点击“show elements”时,只有唯一个 table 和 table 里有 118 行元素。除非在硬件设备取得重大突破,否则要展现 118 行元素还是有点慢的,这使得 UI 测试更具有确定性,不用依赖那些不确定因素如你的设计师或文案。
下面我们一步步重写这个测试,UI 测试的第一步都一样,点击 “show elements” 按钮加载下一个页面
1 | let app = XCUIApplication() |
XCUIApplication
是启动 app 的一个代理,通过这个来进行我们需要的交互和操作。
1 | app.buttons["show elements"].tap() |
.buttons["show elements"]
是 XCUIApplication
实例后提供的一个 XCUIElementQuery
元素查询。我们通过此方法来查找出 “show elements” 这个按钮,如果不存这个名字或存在多个名称的按钮时,会查找失败。当我们通过此方法找到唯一的按钮时,会返回 XCUIElement
这个代理元素,我们就可以使用它的 tap()
方法来模拟点击事件。
XCUIApplication
, XCUIElementQuery
, XCUIElement
这三个 API 就可以完成一次简单 UI 测试,你也可以通过 Xcode 学习到更多的测试方式。
下一步就是我们要确定页面上只有一个 table。
1 | XCTAssertEqual(app.tables.count, 1) |
我们可以结合经常用的 XCTAssert...
到新的 UI 测试中。
确定只有一个 table 后,可以大胆将 assert 移到检查 table 有多少行元素上。
1 | let table = app.tables.elementAtIndex(0) |
以上就是我们在 Xcode 7 上第一次完整的 UI 测试。
完整的测试应该是这样子的:
1 | func testShowElements() { |
我自己对新的框架非常满意,将会不断使用这个框架来自动化测试 app,Apple 给出的信息也十分明确,他们十分重视这系列的 UI 测试,所以我们也应当成为 UI 测试的先行者,推动 UI 测试的发展。
下一步
首先,它会是不错的框架去尝试更复杂的场景,上面的测试标准我们设置的十分简单,只是教我们如何使用新的 UI 测试框架,而不是介绍它如何的强大。
在真实的测试环境中,经常会有网络、动画进入等等各种 app 启动状态和更复杂的使用场景。
另外有趣的是挖掘 UI 测试能否通过命令来启动和在 CI 环境下自动完成测试。
有些翻译不是很好,会继续修改…