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 的所有配置选项:
4. 点击“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/ )
评论