http://www.infoq.com/cn/articles/build-ios-continuous-integration-platform-part3
CI服务器
写到这儿,对于iOS开发者来说,需要准备好:
- 一个比较容易获取的源代码仓库(包含源代码)
- 一套自动化构建脚本
- 一系列围绕构建的可执行测试
接下来就需要一个CI服务器来根据源代码的变更触发构建,监控测试结果。目前,业界比较流行的,支持iOS构建的CI服务器有Travis CI和Jenkins
Travis CI
Travis CI【20】是一个免费的云服务平台,主要功能就是为开源社区提供免费的CI服务,对于商业用户可以使用Travis Pro版本,其基本上支持所有目前主流的语言,Object-C自然也在其中。但是,Travis CI只支持github极大的限制了其应用场景。但是也由于其只支持github,其把和github的集成做到了极致的平滑,易用,因此,对于本就把github作为代码托管平台的项目来说,Travis CI可以做为第一选择。
使用Travis CI只需要简单的2步即可为你托管在github的项目增加一个CI服务器
第一步:在项目的根目录下创建travis CI配置文件“.travis.yml”,在配置文件指定语言,环境要求,构建脚本等
language: objective-c before_install: - brew update - brew install xctool script: xctool -project LighterViewControllerDemo.xcodeproj -scheme LighterViewControllerDemo -sdkiphonesimulator test
第二步:使用github账号登陆Travis CI,在账户的repositories开启该项目的自动构建功能,该设置会在github上该项目repository中开启对Travis CI的Service Hook
下图就是我的一个iOS项目在Travis CI的构建记录:
除此之外,Travis CI还非常贴心的提供了一个指示灯,可以让开发者在自己的repository展示构建状态。使用指示灯的方法很简单,只需要在repository的README.md中添加下面这行代码就行了。
[![Build Status](https://travis-ci.org/xianlinbox/iOSCIDemo.png)](https://travis-ci. org/xianlinbox/iOSCIDemo)
效果如下:
Jenkins
Jenkins【21】经过多年的发展,其活跃的社区和丰富的插件让其成为了业界最受欢迎的CI服务器。通过使用Xcode插件,可以非常方便在Jenkins中运行iOS项目的构建脚本。
安装
Jenkins的安装非常简单,尤其是在Mac环境下使用Homebrew安装,只需要简单的使用“brew install jenkins”,即可成功安装,这个安装过程做的事情非常简单,就是把对应版本的jenkins.war文件下载到对应的目录“/usr/local/Cellar/jenkins/1.524/libexec/”。因此,如果没有Homebrew,可以直接到官网下载安装文件,自己安装。
配置安装完之后,只需要使用“java -jar */jenkins.war”即可启动Jenkins,开发者可以自己创建一个bash alias简化输入,在用户目录下的.bashrc文件中添加如下代码
aliasjenkins='java -jar /Applications/Jenkins/jenkins.war'
启动Jenkins之后,可以通过浏览器访问http://localhost:8080查看Jenkins界面。
然后,开发者可以到Manage Plugins界面,安装需要的插件:Xcode Plugin,Git Plugin,Github Plugin(我使用git做源代码管理),Cocoapods Plugin。安装好插件之后,需要重启Jenkins,一切就绪之后,开始配置自己的iOS构建过程。
在Jenkins中配置一个iOS Job的步骤如下:
- 新建Job,Job类型选择“Build a free-style software project”。
- 配置代码仓库,
-
点击“Add build step”添加构建步骤,如果已安装Xcode插件,则可以在Step类型中看到Xcode选项:
选择Xcode,可以看到Xcode构建step的所有配置选项:
-
点击“Add build step”添加测试步骤,选择“Execute shell”选项,然后,添加脚本,执行测试并生成期望的Report, 可以重复本步骤添加“Acceptaince Test”等构建步骤。
path-to/xctool.sh -workspaceAudioDemo.xcworkspace -scheme AudioDemo -sdkiphonesimulator -reporter junit:test-reports/junit-report.xml clean test
-
点击“Add post-build action”添加一个新的步骤,选择“publish Junit test result report”,把测试报告展示在Jenkins中。
配置好之后,可以点击Build Now运行Job,下图是在Jenkins中运行iOS构建 Job的结果图:
开发者可以点击每次的构建,查看具体的构建信息及测试结果:
常见问题
启动Jenkins提示运行“java”命令需要X11支持,
解决方法:这是因为在OS X Mountain Lion系统中不再内置X11,当需要使用X11时,可通过安装XQuartz project得到支持,具体信息:http://support.apple.com/kb/HT5293
自动化部署
这儿的想谈的“部署”不是传统意义上的直接部署到产品环境的部署,而是指如何把最新版本的应用快速的部署到测试用户的机器上以收集反馈,或者做一些探索性的测试。
在我写第一个iOS应用的时候,我想把应用安装到多个机器上测试的时候,需要非常繁琐的步骤:
- 需要申请到苹果开发者账号,获得开发者证书。
- 需要在苹果的开发者网站上注册我想使用的设备。
- 使用开发者证书打包应用,使用Ad-HOC部署模式,生成ipa文件。
- 通过ipa文件把应用安装到iTunes上。
- 通过iTunes把应用同步到多台测试机器上。
如果是测试机器在多个地理位置的时候,还需要把ipa文件发送到对应的地点,每个地点都需要重复的做第4,5步。 这样一个繁琐,且低效的过程让开发者非常痛苦,直到TestFlight的出现。
TestFlight
TestFlight【22】就是一个专门解决上面提到的痛点的云服务方案,它可以帮助开发者:
- 轻松采集测试用户的UDID和iOS 版本、硬件版本,并发送给开发者。
- 实时反馈应用是否成功安装到测试机器
- 轻松部署最新版本应用到测试用机上。
- 开发者可以灵活选择部署哪个版本到哪部分测试机器上。
使用使用Test Flight服务非常简单,只需要到Test Flight注册一个账号。然后把链接发送给测试设备,测试设备只要打开该链接,并授权给Test Flight,在Test Flight的设备中心就可以看到这些设备。
而测试设备上,则会多一个Test Flight的应用。
当应用有了新的测试包之后,只需要将IPA上传到TestFlight网站,然后勾选合适的测试用户或者合适的设备,点击Update & Notify。
TestFlight会向对应的测试设备发送更新通知,测试用户只需在测试设备上打开TestFlight应用,点击Install,TestFlight就会自动将新版本的IPA文件安装到测试设备上。
另外,TestFlight还提供了Upload API,这样就等于提供了和CI服务器集成的能力。其Upload API非常简单,就是一个简单的,带有指定参数的HTTP POST请求,具体细节可参考官网:https://www.testflightapp.com/api/doc/。
在 CI服务器中,开发者可以在构建过程中,添加步骤通过upload API把通过测试的ipa文件自动上传到TestFlight上,从而达到持续部署的目的。而像Jenkins这样有丰富插件机制的CI服务器, 活跃的社区开发者们早为其开发了十分便于使用的TestFlight的插件。
在Jenkins中使用TestFlight插件也非常简单,安装好插件,重启Jenkins,然后在项目的构建过程配置页面的Post-build Actions中,点击add post-build action,可以看到Upload to Testflight选项:
选择之后,可以在页面上看到TestFlight的配置项:
为了增强安全性,该插件把Token的设置移到了Jenkins的Global Setting界面:
配置好Token Pair之后,在在TestFlight的配置项 上选择相应的pair即可,设置想要的参数,保存即可。
你如果不喜欢使用插件或者说使用的其它CI服务器的话,可以通过添加一个Execute shell步骤,直接通过代码上传构建好的ipa文件:
curl http://testflightapp.com/api/builds.json -F file=@testflightapp.ipa -F dsym=@testflightapp.app.dSYM.zip -F api_token='your_api_token' -F team_token='your_team_token' -F notes='This build was uploaded via the upload API' -F notify=True -F distribution_lists='Internal, QA'
结语
《持续集成》一书中引用了Javaranch.com的创始人Kathy Sierra的一句话:
There's a big difference between saying, "Eat an apple a day" and actually eating the apple
正所谓知易行难,您几乎很难听到开发者说:“持续集成毫无价值”,但是,构建一个持续集成平台并非易事,希望本文中介绍的iOS应用的构建过程,以及在构建过程的各个阶段可以使用的一些优秀的类库,服务,能够让iOS开发者们在想搭建一个持续集成平台时有所参考,从而能够更加坚定,且容易的为自己的项目搭建一个持续集成平台。
参考文献
- Matin Fowler’s Blog: Continuous Integration(http://martinfowler.com/articles/continuousIntegration.html)
- Continuous Integration: Improving Software Quality and Reducing Risk(http://www.amazon.com/gp/product/0321336380?ie=UTF8&tag=martinfowlerc-20&linkCode=as2&camp=1789&creative=9325&creativeASIN=0321336380)
- XCodeBuildMannualPage(https://developer.apple.com/library/mac/documentation/Darwin/Reference/ManPages/man1/xcodebuild.1.html)
- XCodeConcepts(http://developer.apple.com/library/ios/#featuredarticles/XcodeConcepts/Concept-Schemes.html#//apple_ref/doc/uid/TP40009328-CH8-SW1)
- Running OCUnit (or Specta) Tests from Command Line(http://www.raingrove.com/2012/03/28/running-ocunit-and-specta-tests-from-command-line.html)
- xctool(https://github.com/facebook/xctool)
- cocoapods(http://cocoapods.org/)
- cocoapods:contributing _to_the_master_repo(http://docs.cocoapods.org/guides/contributing_to_the_master_repo.html)
- Using Open Source Static Libraries in Xcode 4(http://blog.carbonfive.com/2011/04/04/using-open-source-static-libraries-in-xcode-4/#creating_a_workspace)
- Test Pyramid(http://martinfowler.com/bliki/TestPyramid.html)
- OCUnit(http://cocoadev.com/OCUnit)
- GHUnit(http://gabriel.github.io/gh-unit/)
- OCHamcrest(https://github.com/hamcrest/OCHamcrest)
- OCMock(http://ocmock.org/)
- moco(https://github.com/dreamhead/moco)
- 企业系统集成点测试策略(http://www.infoq.com/cn/articles/enterprise-systems-integration-points)
- UIAutomation(http://developer.apple.com/library/ios/#documentation/DeveloperTools/Reference/UIAutomationRef/_index.html)
- Fone Monkey(http://www.gorillalogic.com/fonemonkey-ios)
- Travis CI(http://about.travis-ci.org/docs/)
- WWDC 2010 Session 306:Automating User Interface Testing with Instruments(http://developer.apple.com/devcenter/download.action?path=/wwdc_2010/wwdc_2010_video_assets__pdfs/306__automating_user_interface_testing_with_instruments.pdf)
- Jenkins(http://jenkins-ci.org/)
- TestFlight(https://testflightapp.com/)