构建iOS持续集成平台(二)——测试框架
来源:互联网 发布:巨灵数据 编辑:程序博客网 时间:2024/05/01 21:56
【原文地址:http://www.infoq.com/cn/articles/build-ios-continuous-integration-platform-part2#0-tsina-1-33218-397232819ff9a47a7b7e80a40613cfe1】
测试框架
有了自动化构建和依赖管理之后,开发者可以很轻松的在命令行构建整个项目,但是,作为持续集成平台来说,最重要的还是测试,持续集成最大的好处在于能够尽早发现问题,降低解决问题的成本。而发现问题的手段主要就是测试。在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>
开发者可以把这段代码加入<TestTargetName>-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的头文件添加<TestTargetName>-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测试脚本
指定目标设备,构建被测应用,该应用会被安装到指定的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
启动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的形式运行测试。
- 构建iOS持续集成平台(二)——测试框架
- 构建iOS持续集成平台(二)——测试框架
- 构建iOS持续集成平台
- 构建iOS持续集成平台(一)——自动化构建和依赖管理
- 构建iOS持续集成平台(一)——自动化构建和依赖管理
- 构建iOS持续集成平台(一)——自动化构建和依赖管理
- 持续集成(二)环境搭建篇 — .Net 平台程序构建真相
- 构建iOS持续集成平台(三)——CI服务器与自动化部署
- 构建iOS持续集成平台(三)——CI服务器与自动化部署
- 构建iOS持续集成平台(三)——CI服务器与自动化部署
- 持续集成平台构建
- 构建持续集成平台
- NT_iOS笔记—持续集成Jenkins(自动化构建打包)
- 第4代白盒测试方法实践之“使用VcTester构造持续集成及每日构建平台”
- Jenkins构建iOS持续集成环境(一)
- 搭建持续集成接口测试平台(Jenkins+Ant+Jmeter)
- 搭建持续集成接口测试平台(Jenkins+Ant+Jmeter)
- 搭建持续集成接口测试平台(Jmeter+Jenkins+Ant)
- java io 学习之三 字符流的缓冲区
- 欢迎使用CSDN-markdown编辑器
- XIB设置圆角
- JAVA国际化
- sharedpreferance fragment 五种存储方式
- 构建iOS持续集成平台(二)——测试框架
- 创建第一个Xamarin.android application
- 设计模式系列之 模式概述
- Paraview模型颜色问题
- 高级android高斯模糊技术-媲美IOS
- python中range和xrange的异同
- #job 40
- webService
- nginx缓存配置