滴墨书摘 iOS UI自动化测试方案

引言

对于独立开发者来说, 测试资源一直是非常头疼的问题. 对于传统手点的方式, 需要花费非常多的时间在测试上.

GUI应用, 单测能做到的事情很少, 集成测试的地位非常重要.

大部分人在编写UI测试代码的时候, 会大量判断视图的位置和排版.

不幸的是, 和逻辑不同, UI总是改变.
我相信这是大部分人没有坚持下去的原因.

如果通过编程的形式去编写UI测试, 后续会带来大量的维护成本, 我们会花大量时间在修改原有的用例上.

我在日常的独立开发中, 摸索出一套方案. 并在 滴墨书摘 当中使用.

如果去避免编码的形式去校验UI是否正确?

其实我们可以从另一个方面入手. 可以通过对每一步关键操作进行截图, 并在测试结束后对外输出一组截图. 通过截图去判断结果是否正确.

这样又会带来另外的问题. 例如, 截图怎么去判断是否正确? 如果完全基于肉眼去校验, 一来费时费力, 其次细微的调整, 肉眼难以捕捉到差异.

实际上我们可以在首次执行后, 肉眼订正, 并制定一套作为”正确结果”的截图组. 之后执行的 UI 测试所产出的截图, 用程序将其与正确答案进行对比, 并输出两者之间的差异.

选型

UI Testing 选型

在技术选型上, 首先就是UI 自动化框架. 处理Apple提供的UIAutomation之外, 市面上有不少三方框架. 这里我仅简要挑几个进行说明.

  • [❌] Appium

Appium 是一个跨平台的UI自动化框架. 使用 Python 语言开发. 同时支持 Android 和 iOS.

Appium 是工程化测试的一种选择. 但针对于 iOS 开发者来说, 它将 UI 自动化变得更加复杂, 原先 iOS 的开发经验没有什么太大帮助.

  • [❌] KIF

KIF 是一个老牌的iOS UI 自动化三方库. 它由 Object-C 开发, 基于原生的UnitTesting, 通过私有API事先UI自动化功能. 针对 iOS 开发而言, 它非常友好.

但将测试任务变成编程任务的一部分, 是非常消磨耐心的. 即使它提供了不少的语法糖, 但是通过编程完成 UI 自动化还是非常劳累. UI与逻辑不同的一个地方在于, 它总是在变.

  • [☑️] UIAutomation

UIAutomation 是Apple原生提供的 UI 自动化方案. 它最低支持 iOS 9. Xcode 配套开发工具提供了一整套的 Record 功能. 开发者可以通过录制自动生成 UITests 代码. Record 生成的代码是 XCTest 框架的代码. 所以最终我并没有使用其他三方的测试框架, 而选用的原生的 UIAutomation 进行UI自动化测试. 我期望通过 Record 协助去编写UITests代码.

Record 生成的代码虽然冗余, 但依旧能减轻不少的工作, 我在编写 UITests 时, 先通过 Record 生成代码, 接着手动修改.
这个过程反复贯穿着整个测试代码的编写过程.

在 UI Testing 选型结束后, 已经可以达到免手工测试了. 但仅仅只是这样, 我们每次执行都需要手动打开Xcode工程去执行, 而且过程需要人为监督. 其次, 在上面提到的每一个关键点进行截图, 如果有效的输出到对应的目录?

fastlane screenshots

fastlane 是一套支持Android和iOS的自动化工具. 它提供了一组自动化的便捷解决方案. 包含打包,部署,签名,生成屏幕截图 等等的功能. 它提供了一组强大的CLI以方便开发者使用.

其中, screenshots 是 fastlane 的一个功能(也可以称之为插件). 它通过 UI Testing 自动截取并输出屏幕截图. 以供开发者便捷生成 App Store 的屏幕截图.

在这里, 我们使用 screenshots 有另外的用途, 我们通过它去生成UI Testing 过程中产生的截图.

通过 fastlane screenshots, 我们可以做到在终端中运行不同设备的UI测试, 并且将每个设备的测试截图输出在指定文件夹中.

ImageMagick

ImageMagick 是一个跨平台图像处理软件, 可以在命令行中完成绝大多数图像处理. 他除了提供 CLI 工具之外, 还有多种语言的三方包可以方便开发者在其基础上进行二次开发.

通过 ImageMagick 可以对比两个图片是否有差异.

CLI中通过 compare 命令对比两张图片, 并输出差异

$ compare bag_frame1.gif bag_frame2.gif compare.gif

output:

如果我们期望输出一个数值, 以判断两张图片是否相同. 可以添加 -metric RMSE 参数, 它将输出一个结果.:

$ compare -metric RMSE bag_frame1.gif bag_frame2.gif compare.gif

output:

11298.6 (0.172405)

如果该结果为 0 时, 则两张图片相同.

相关 ImageMagick文档:
compare 命令文档: Comparing — IM v6 Examples
metric 参数文档: Command-line Options @ ImageMagick

示例

ty0x2333/ios-ui-automation