我们遇见的问题:

  客户端项目总是希望可以更快的拿出一个可用的版本,尽早的让内部的同学试用这个新的客户端,尽早的收集意见,尽早的修复问题,优化设计;同样开发的同学在代码修改的过程中也希望能够更快的收到反馈。这要求客户端的测试能够更快捷的响应,尽快的回归新版本,及时的反馈问题,尽早的发出稳定的新版本来提供内测。因此客户端的测试产生了这些需求:

  <!--[if !supportLists]-->1) <!--[endif]-->开发提交代码之后尽可能快的发现和反馈问题;

  <!--[if !supportLists]-->2) <!--[endif]-->更快的进行功能回归,保证开发的修改不会对已有功能产生影响;

  <!--[if !supportLists]-->3) <!--[endif]-->尽快的提供一个稳定版本用于内测,以方便更好的提升产品质量;

  从上面的需求上来看,出现了一个迭代,发布一个新版本内测带来了使用者的反馈和建议,于是开发修改了代码以提升质量,于是又发布了一个新版本提供内测,新版本又会带啦新的建议和反馈,如此迭代着前进,于是项目质量越来越好,用户体验也越来越好,很美好的一个事情;

  但是往往现实比较骨感,这样的一个迭代节奏一旦被打破了,那么带来的往往是一种灾难,不停的发布新版本,结果问题越来越多,内测用户越来越少,整个项目组的人反而越来越累;

  为了避免这样的问题发生,不让一些坏的味道破坏项目的节奏,让整个项目更好的运转需要满足上面的这些需求,同时尽量让这些需求做到更加的自动,减少人的参与,本地生活业务线在这样的情况下开始了尝试,去试着形成自己的节奏,解决自己的问题。

  在这里说一说本地生活业务线的持续集成,和大家一起沿着这条路走走:

  初的分析:

  首先想到的第一点,自动化。那么如何来做iOS客户端的自动化测试呢?话说站在巨人的肩膀上,对于本地生活也是如此;于是开始对于自动化的框架进行选型,调研了不少的团队,终选择使用athrun来做本地生活的自动化框架,原因也很简单:第一,团队和个人来说,对于Java比较熟悉,虽然使用Javascript可以带来录制的便利,但是从长远来看使用athrun对于团队来说效率应该更高,学习成本也会比较低;第二,使用athrun很好的和JUnit集成起来,而JUnit的框架比较成熟,带来断言,日志等便利,可以丰富脚本运行时的日志,便于后期对于结果的分析;当然了,主要的原因还是因为第一条,学习成本比较低,对于语言比较熟悉;

  继续深入下去,发现athrun在运行的时候需要提供一个app文件,如此带来了一个新的问题:如何保证我测试的这个app包是新的,怎么更快的获取这个包,怎么减少人工干预?一般测试过程中工程都是通过Xcode来进行build的,那么是否存在另外的方式来解决这个问题呢?经过学习之后发现Xcode提供了命令行工具,通过这个工具可以使用命令行来build工程,自动打包;那么是不是可以通过一段shell命令完成这个工作呢?于是写了一个shell脚本来进行项目的build工作,在每次执行自动化脚本之前build一下新的包,那么自动化脚本的执行的app是新的了;

  好的,自动化的工作由此展开,然后新的问题又出现了,项目进行到后期开发提交的代码的环境设置往往是预发布环境,而自动化运行的环境是测试环境,更悲剧的是发布到内测的版本的环境是线上环境,如此三个环境的切换开始了,懒人总是希望不要将这些繁琐的事情让自己来完成,于是想尽办法来偷懒,结果选择了一个笨的方式,通过shell来做环境切换;对于不同的环境建立不同的版本,在版本build之前先将环境做修改以满足不同的需求;

  要发布第一个内测版本的包了,还是蛮开心的,丑媳妇终于要见公婆了,却被告知啥要提交一个ipa包,对于我这样一个之前从没有使过苹果的低端用户简直是一个基础扫盲,被发配回去重新研究生成ipa包,开始的时候使用Xcode来生成ipa包,每次上传之前先自己生成一下,然后再上传。但是这对于一个懒人是怎样的一种折磨啊,于是去想办法偷懒,发现jenkins中提供了一个Xcode Plugin的插件,这个插件不但可以进行项目的build还可以生成ipa包,好吧,前面的功夫白费了,弃暗投明呗!

  这三个多月以来一直在解决着自己的问题,在这个过程中遇见了很多问题,也解决了很多的问题,通过解决这些问题对于初的三个需求有了更深的思考,于是随手拿起笔涂鸦一下。

  进一步思考:

  目前本地生活的iOS客户端已经有2个在AppStore上发布,在这两个项目中对于上面的部分都进行了实践,梳理出了如下的流程:

  这个过程中形成了一套适合自己的持续集成的过程,在开发提交代码之前对于代码进行静态扫描,将除去第三方库以外的问题修复,之后提交的代码将会被Xcode Plugin进行build,在build过程中将将会对于不同的需求构建不同的包,在其中用于自动化回归的包上执行自动化脚本,对于稳定版本(自动化测试通过)的正式ipa包上传至内测版本下载服务器;其主要的步骤包括以下部分:

  <!--[if !supportLists]-->1) <!--[endif]-->更新新代码;

  <!--[if !supportLists]-->2) <!--[endif]-->静态分析;对于代码进行静态检查,Xcode使用的静态检查工具为Clang Static Analyze,该工具可以监测出代码中潜在的内存泄露、使用未赋值变量、变量申明后未使用等问题,如果发现了相应的问题,通知开发进行修复(目前这一步骤没有通过自动的方式来实现,还是通过和开发的规约来保证,再之后会将这部分自动化实现);

  <!--[if !supportLists]-->3) <!--[endif]-->版本构建;针对不同的需求构建不同的版本,这步是通过Xcode Plugin来实现,Xcode Plugin使用的仍然是xcodebuild命令行,在这一步骤中需要提供环境切换的脚本,而不同的项目可能开发实现环境切换的方式都不同,因此这里经常是让人很抓狂的地方,需要和开发进行进一步的沟通共同确定环境切换的规约。在构建之后需要对于这些修改进行还原操作,不要遗漏修改的代码还原;