QCon北京「鸿蒙专场」火热来袭!即刻报名,与创新同行~ 了解详情
写点什么

构建 iOS 持续集成平台(二)——测试框架

  • 2013-09-17
  • 本文字数:4494 字

    阅读完需:约 15 分钟

测试框架

有了自动化构建和依赖管理之后,开发者可以很轻松的在命令行构建整个项目,但是,作为持续集成平台来说,最重要的还是测试,持续集成最大的好处在于能够尽早发现问题,降低解决问题的成本。而发现问题的手段主要就是测试。在 Martin Fowler 的 Test Pyramid【10】一文中论述了测试金子塔的概念,测试金字塔的概念来自 Mike Cohn ,在他的书 Succeeding With Agile 中有详细描述:测试金字塔最底层是单元测试,然后是业务逻辑测试,如果更细化一点的话,可以分为把完整的测试策略分为如下的层级:

作为持续集成平台,能自动化的测试层级越多,平台就能产生越大的价值。

Unit Test

目前,在 iOS 领域, 最流行的 Unit 测试框架有 2 个:OCUnit【11】和 GHunit【12】,这两个框架各有其优缺点:

优点

缺点

OCUnit

与 Xcode 无缝集成, 快捷键,Scheme 配置都非常方便

1. 只能一次运行整个测试,不能灵活的运行某个测试集 ; 2. 测试结果输出的可读性不好,不容易找到失败的测试

GHUnit

1. 自带 GUI,测试结果清晰可见;2. 可以灵活的运行指定的测试;3. 开源项目

1. 需开发者安装,配置略显复杂;2. 对命令行运行测试的支持不是很好,

OCUnit 的运行结果会通过弹窗直接告诉开发者,运行的细节信息则会打印在 Xcode 的输出窗口中:

GHUnit 的运行结果则全部显示在自己的应用界面中,开发者可以在应用中查看所有的信息,以及做运行测试等各种各样的操作。

关于如何使用 OCUnit 和 GHUnit, InfoQ 上有高嘉峻的文章《iOS 开发中的单元测试》( http://www.infoq.com/cn/articles/ios-unit-test-1)有详细的介绍,我就不再这儿重复叙述了。

如果单从单元测试框架来看,个人更喜欢 GHUnit 测试结果的可读性和运行测试的灵活性,但是,随着 Facebook 的 xctool 的发布,OCUnit 华丽丽的逆袭了,因为 xctool 帮助 OCUnit 把运行测试的灵活性和测试结果的可读性这两块短板给补齐了,再加上其和 Xcode 的集成优势以及通过命令行运行的便捷性,让其成为持续集成平台的 Unit 测试框架的首选。

在 Java 程序员的心中,Junit 和 Hamcrest 永远是一体的,Hamcrest 为 junit 提供了非常丰富的断言机制,极大的增强了测试的可读性。越来越活跃的 iOS 开发社区,当然不会让 Object-C 的世界缺失这样一个优秀的框架,于是 OCHamcrest【13】诞生了。

在测试项目中使用 OCHamcrest 非常简单,尤其是使用了 cocoapods 管理依赖的项目。只需要在 Podfile 文件中加上:

复制代码
target :<TestTargetName> do
...
pod 'OCHamcrest'
end

然后,运行“pod install”命令安装 Hamcrest 到测试 Target,安装好之后,为了在测试类中使用 OCHamcrest 的断言。还需要在测试类的头文件中加入如下代码:

复制代码
#define HC_SHORTHAND
#import<OCHamcrest/OCHamcrest.h>

开发者可以把这段代码加入-prefix.pch 中,这样所有的测试类就都可以使用 OCHamcrest 的断言了。在前面提到的高嘉峻的文章中的第二部分更加详细的讲解了 OCHamcrest 的断言,以及其和另一个断言框架 Expecta 的对比,感兴趣的同学可以跳过去看看( http://www.infoq.com/cn/articles/Matching-Engine-Enliven-Assertion-2?utm_source=infoq&utm_medium=related_content_link&utm_campaign=relatedContent_articles_clk )。

Component Test & Integration Test

在开发手机应用时,总难免会和其他的系统集成,尤其当开发的应用是某个系统的手机客户端时,这样就涉及到很多第三方 API 的集成点需要测试,在成熟的 Java 世界中,诞生了 EasyMock,Mockito,moco 等针对这种集成点的测试工具。同样的,活跃的社区力量正一步一步的在让 Object-C 世界成熟,OCMock【14】诞生。

OCMock

有了 cocoaPods,新加框架变得非常容易,基本上就是“哪里没有加哪里”的节奏,添加 OCMock 框架,只需要在 Podfile 文件中加上:

复制代码
target :<TestTargetName> do
...
pod 'OCMock', '~> 2.0.1'
end

然后,运行“pod install”命令安装 OCMock 到测试 Target,同样的,需要把 OCmock 的头文件添加-prefix.pch 文件中

复制代码
#import<OCMock/OCMock.h>

下面是一个简单的使用 OCMock 的例子,更多的用法请参考 OCMock 的官网: http://ocmock.org/features/:

复制代码
- (void)testSimpeMockPass{
idmockObject = [OCMockObjectmockForClass:NSString.class];
[[[mockObject stub] andReturn:@"test"] lowercaseString];
NSString * returnValue = [mockObjectlowercaseString];
assertThat(returnValue, equalTo(@"test"));
}

moco

moco【15】以其对系统集成点测试的贡献荣获了 2013 年的“Duke’s Choice Award”奖,虽然其以 Java 写成,主要的生态系统也是围绕 Java 打造,但是,其 Standalone 模式可以非常方便的构造一个开发者期望的服务器,这对于 Mobile 领域的集成点测试来说,本就是一个非常好的 Mock 服务器的工具。Moco 有如下的特点:

  • 易于配置,使用:一个 Json 配置文件,然后“java -jar moco-runner–standalone.jar -p 8080 ***.json”就可以启动一个 Mock 服务器。该服务器的所有行为都在配置文件里。如果你想添加,修改服务器行为,只需要修改一下配置文件,然后重新启动该服务器就行了。
  • 配置文件可读性好,使用 Json 格式的配置文件,对绝大多数开发者来说都可以很容易理解。
  • 支持模拟客户端需要的所有 http 操作,moco 实现了针对请求 Content、URI、Query Parameter、Http Method、Header、Xpath 的模拟。对响应的格式支持有 Content、Status Code、Header、URL、甚至支持 Sequence 请求,即根据对同一请求的调用次数返回不同的结果。
  • 完全开源,代码不多也比较易懂,如果没有覆盖到我们的场景,完全可以在该项目基础上实现一个自己的 Mock 服务器 。

熊节在 infoQ 上发表的《企业系统集成点测试策略》【16】一文中,详细的论述了在企业系统中,moco 对测试系统集成点的 帮助。这些论点在 Mobile 开发领域同样适用,因此合理的使用 moco 可以帮助 iOS 开发者更加容易的构建一个稳固的持续集成平台。

System Test

对于 iOS 的系统(UI)测试来说,比较知名的工具有 UIAutomation【17】和 FonMonkey【18】。

UIAutomation

UIAutomation 是随着 iOS SDK 4.0 引入,帮助开发者在真实设备和模拟器上执行自动化的 UI 测试。其本质上是一个 Javascript 的类库,通过 界面上的标签和值的访问性来获得 UI 元素,完成相应的交互操作,从而达到测试的目的,类似于 Web 世界的 Selenium。

通过上面的描述,可以得知,使用 UIAutomation 做测试时,开发者必须掌握两件事:

  • 如何找到界面上的一个 UI 元素
  • 如何指定针对一个 UI 元素的操作

在 UIAutomation 中,界面就是由一堆 UI 元素构建的层级结构,所有 UI 元素都继承对象 UIAElement ,该对象提供了每个 UI 元素必须具备的一些属性:

  • name
  • value
  • elements
  • parent

而整个界面的层级结构如下:

复制代码
Target(设备级别的 UI,用于支持晃动,屏幕方向变动等操作)
Application(设备上的应用,比方说 Status Bar,keyboard 等)
Main window(应用的界面,比方说导航条)
View(界面下的 View,比方说 UITableView)
Element(View 下的一个元素)
Child element(元素下的一个子元素)

下面是一个访问到 Child element 的例子:

复制代码
UIATarget.localTarget().HamcrestDemo().tableViews()[0].cells()[0].elements()

开发者还可以通过“UIATarget.localTarget().logElementTree()”在控制台打印出该 target 下所有的的 elements。

找到 UI 元素之后,开发者可以基于该 UI 元素做期望的操作,UIAutomation 作为原生的 UI 测试框架,基本上支持 iOS 上的所有 UI 元素和操作,比方说:

  • 点击按钮,例: ***.buttons[“add”].tap()
  • 输入文本, 例:***.textfields[0].setValue(“new”)
  • 滚动屏幕,例:***.scrollToElementWithPredicate(“name begin with ’test’”)
  • ……

关于使用 UIAutomation 做 UI 测试,推荐大家一定要看一下 2010 的 WWDC 的 Session 306: Automating User Interface Testing with Instruments 【19】。 另外,这儿还有一篇很好的博客,详细的讲解了如何使用 UIAutomation 做 UI 自动化测试: http://blog.manbolo.com/2012/04/08/ios-automated-tests-with-uiautomation

Apple 通过 Instruments 为 UIAutomation 测试用例的命令行运行提供了支持,这样就为 UIAutomation 和 CI 服务器的集成提供了便利。开发者可以通过如下的步骤在命令行中运行 UIAutomation 测试脚本

  1. 指定目标设备,构建被测应用,该应用会被安装到指定的 DSTROOT 目录下
复制代码
xcodebuild
-project "/Users/twer/Documents/xcodeworkspace/AudioDemo/AudioDemo.xcodeproj"
-schemeAudioDemo
-sdk iphonesimulator6.1
-configuration Release SYMROOT="/Users/twer/Documents/xcodeworkspace/
AudioDemo/build" DSTROOT="/Users/twer/Documents/xcodeworkspace/AudioDemo/
build" TARGETED_DEVICE_FAMILY="1"
install
  1. 启动 Instruments,基于第一步生成的应用运行 UIAutomation 测试
复制代码
instruments
-t "/Applications/Xcode.app/Contents/Applications/Instruments.app/
Contents/PlugIns/AutomationInstrument.bundle/Contents/Resources/
Automation.tracetemplate" "/Users/twer/Documents/xcodeworkspace/AudioDemo
/build/Applications/TestExample.app"
-e UIASCRIPT <absolute_path_to_the_test_file>

为了更好的展示测试效果以及与 CI 服务器集成,活跃的社区开发者们还尝试把 UIAutomation 和 Jasmine 集成: https://github.com/shaune/jasmine-ios-acceptance-tests

UIAutomation 因其原生支持,并且通过和 Instruments 的绝佳配合,开发者可以非常方便的使用录制操作自动生成测试脚本,赢得了很多开发者的支持,但是因苹果公司的基因,其系统非常封闭,导致开发者难以扩展,于是活跃的社区开发者们开始制造自己的轮子,Fone Monkey 就是其中的一个优秀成果。

Fone Monkey

Fone Monkey 是由 Gorilla Logic 公司创建并维护的一个 iOS 自动化测试工具,其功能和 UIAutomation 差不多,但是由于其开源特性,极大的解放了活跃开发者的生产力,开发者可以很容易的根据自身需要扩展其功能。

Fone Monkey 的安装虽然简单,但是比 UIAutomation 的原生支持来说,也算是一大劣势了,具体的安装过程可以参考: http://www.gorillalogic.com/fonemonkey-ios/fonemonkey-setup-guide/add-fonemonkey-your-xcode-project

Fone Monkey 的使用方式主要就是录制 / 回放,也可以把录制好的测试用例保存为脚本以其他方式运行。安装好 Fone Monkey 启动测试以后,应用界面会有点变化:

开发者通过点击 Record 按钮录制操作,点击 Play 按钮播放之前录制的操作,点击 More 按钮可以添加一些针对元素的验证, 这样就形成了一个测试用例。

在 Fone Monkey 中录制的测试用例可以保存为 3 种格式,以支持多种运行方式:

  • scriptName.fm:用于支持在 Fone Monkey 的窗口中运行测试
  • scriptName.m:用于和 Xcode 的 OCUnit test 集成,可以以 OCUnit 的测试用例的形式运行 UI 测试,这就让 UI 具备了命令行运行和与 CI 集成的能力。
  • scriptName.js:UIAutomation 的格式,用于支持在 Instruments 中,以 UIAutomation 的形式运行测试。
2013-09-17 03:4010860

评论

发布
暂无评论
发现更多内容

Mac上超好用的鼠标平滑滚动增强工具:SmoothScroll

Rose

Mac软件 鼠标工具 SmoothScroll 平滑滚动

DRM音频格式转换好帮手-NoteBurner iTunes DRM Audio Converter 兼容M1和macos14系统

Rose

DRM 音频转换器

Live Home 3D Pro for Mac(苹果电脑3D室内家居设计软件)

Rose

Mac软件 Live Home 3D Pro 家居设计软件 Live Home 室内设计

2024-01-24:用go语言,已知一个n*n的01矩阵, 只能通过通过行交换、或者列交换的方式调整矩阵, 判断这个矩阵的对角线是否能全为1,如果能返回true,不能返回false。 我们升级一下:

福大大架构师每日一题

福大大架构师每日一题

什么是网络地址转换协议

郑州埃文科技

夏志刚介绍

管理在线

企业战略管理体系 企业精益管理体系 企业创新管理类体系 企业培训体系 企业标准化管理体系

mac系统u盘启动盘制作教程,更新至macOS Sonoma 14

Rose

mac系统

权威媒体评选:2023年25个最佳开源软件

SEAL安全

开源 AI LLMs

K8s集群CoreDNS监控告警最佳实践

华为云开发者联盟

开发 华为云 k8s集群 华为云开发者联盟

一篇全掌握!TDengine 在能源、电力、汽车、物流、工业制造等十大行业应用合集

TDengine

tdengine 时序数据库

基于Express的微信公众号开发

派大星

Express 微信公众号开发

CDP技术系列(二):ClickHouse+Bitmap实现海量数据标签及群体组合计算

京东科技开发者

光纤的跳线和尾纤

小齐写代码

华为云云绘本第2期:面对等保三级,谁还在瞎折腾?

华为云PaaS服务小智

软件开发 华为云

uniapp+unicloud开发一个网页端,小程序端,APP端,桌面端的博客CMS系统——万能的三三

万能的三三

JavaScript 小程序 uni-app CMS 博客

左耳听风 - 时间管理「读书打卡 day 15」

Java 工程师蔡姬

读书笔记 程序员 个人成长 时间管理 职业发展

BricsCAD 24 mac中文完美破解版(CAD建模软件) 支持M和 macOS Sonoma 14 附安装教程

Rose

BricsCAD 23中文版 cad bricscad 24 BricsCAD 24破解版 BricsCAD 24下载

用Python实现高效数据记录!Web自动化技术助你告别重复劳动!

测试人

软件测试

【Linux技术专题】「夯实基本功系列」带你一同学习和实践操作Linux服务器必学的Shell指令(排查问题指令 - 下)

码界西柚

Linux 日志处理 Shell指令 查询日志 2024年第二十篇文章

融合创新:传统企业数字化转型的业务、战略、操作和文化变革

天津汇柏科技有限公司

数字化转型

PD虚拟机系统镜像 原版纯净的Windows系统安装包

Rose

windows 11 pd虚拟机 win系统下载

有挑战才有收获!PaddleOCR算法模型挑战赛火热开启!

飞桨PaddlePaddle

人工智能 算法 大赛 百度飞桨 算法模型

CDP技术系列(一):使用bitmap存储数十亿用户ID的标签或群体

京东科技开发者

数值计算: 精度、溢出、舍入

西格玛

CDP技术系列(三):百万级QPS的人群命中服务接口性能优化指南

京东科技开发者

数仓如何递归查询视图依赖

华为云开发者联盟

数据库 后端 华为云 华为云开发者联盟 华为云GaussDB(DWS)

Wireshark网络工具是什么?

小齐写代码

构建iOS持续集成平台(二)——测试框架_DevOps & 平台工程_刘先宁_InfoQ精选文章