【转载】敏捷开发 -- 持续集成

上一篇 / 下一篇  2010-06-17 23:29:22 / 个人分类:开发

软件集成并不是一个新的问题或者概念,当一个人独立开发一个产品的时候,比如做毕业设计的时候,根本就不存在软件集成,更不用去考虑持续集成!可到了三五个人、七八条枪,进行团队开发的时候,这个问题就不得不去考虑了!特别是在传统的瀑布式开发中,模块开发是独立进行,当各个模块都完整开发完了之后,再进行模块间的整合,很多噩梦都发生在这个时候:接口不统一,模块间对需求的理解不一致……往往要磨上十天半个月才能搞定!
       Martin FowlerThoughtWorks公司的那个“大胡子”)对持续集成的注解如下:
      Continuous Integration is a software development practice where members of a team integrate their work frequently, usually each person integrates at least daily - leading to multiple integrations per day. Each integration is verified by an automated build (including test) to detect integration errors as quickly as possible. Many teams find that this approach leads to significantly reduced integration problems and allows a team to develop cohesive software more rapidly.
    我觉得可以这样简单理解:及早地将开发人员的代码集成起来,通过各种工具来及时地发现代码中存在的问题,以确保代码质量的稳定性和准确性,让Agile第二宣言Working Software得以实现!
  下面我们按照Martin Fowler的思路来介绍持续集成:
     1)Maintain a Single Source Repository
  一般来说,工程都是以团队的形式进行开发的。一个工程的文件都是以千百计算的,如果需要手工去跟踪、同步这些文件,那无疑是天方夜谭。于是源代码管理工具应运而生。开源的源代码管理工具有CSVSubversion等,个人感觉Subversion比较好用,另外由IBM Rational出品的Clearcase功能更是强大,不过不是很便宜。我们可以在这些源代码管理工具上面创建一个工程的Stream,然后大家便可以在这个Stream上面建立自己的Child Stream,在代码进行改动之后,我们就将这些代码Deliver到代码库,代码的管理工具会为我们做代码的同步工作。这样大家就可以基于最新的代码进行开发。
  2)Automate the Build  
  从拿到源代码到变成一个可运行的系统,这中间要经过一个复杂的过程。一个简单的过程大概有:编译/打包源代码,将打包好的包拷贝到服务器下面,然后启动或者重启服务器,这是简单到有点“HelloWorld”的感觉。即使在这么简单的过程中,还得开启IDE才能让编译源代码方便些,可在集成的服务器中,一般是不会使用IDE的。开发人员“懒惰”的特性迫使他们开发新工具来完成这一烦人的过程。Java社区开发出Ant.NET社区开发出Nant,现在还有MSBuild。通过这些工具,我们可以将这些复杂、重复、单调、无聊的工作通过一些配置交由工具去完成。由于Ant的功能确实很强大,以后再找时间补充Ant的使用。
  3)Make Your Build Self-Testing  
  在传统的开发模式中,当build一个版本出来之后,我们往往需要叫上所有的人(因为是分模块开发),花上几个钟头,在系统上进行人工测试。而郁闷的是:即使进行了人工测试,表面上看似没有问题了,可保证不了后台逻辑的正确性。我们不是有Automake the Build吗,那我们就可以往里面加进一些自动化测试的任务。这些自动化测试在build的过程中,检测代码的逻辑的正确性、分析代码的复杂度、指出代码潜在的危险性,测试系统功能的完整性和准确性,测试系统的行为等等。当然,不是说我们往Ant脚本里面加进几条命令就可以完成这些功能,而是需要我们在写功能代码的同时或者之前,编写相应的测试代码,这就是前面说的Test Driven DevelopmentTDD,测试驱动开发),先写测试,再写实现!一般来说,测试包括了后台逻辑测试(一般用NUnit),测试前台脚本逻辑(Javascript的脚本一般用JsUnit),测试页面功能行为正确性(一般用Selenium),分析代码的复杂度(可以用PMD),分析代码潜在的危险性(用FindBugs)。
  4)Everyone Commits Every Day  
  集成很多时候是为了沟通,告诉其他开发人员自己已经做了那些代码的改动。及时的沟通在团队开发中的重要性是不容置疑的。所以我们要尽快地将自己代码的改动提交。但代码提交之前,一定要确保自己代码的正确性,至少让系统可以跑起来。而不是说代码一有改动,就不管三七二十一,把代码弄上去就行了,这样对整个团队来说,cost会更大!所以是否每一天都要提交代码呢,我觉得要具体问题具体分析!
  5)Every Commit Should Build the Mainline on an Integration Machine  
  前面说到每天都提交代码,这就会带来一个问题:在提交代码之前,未必有去拿到最新代码,即使拿到最新代码,由于开发环境的不同,也可能没发现什么问题。于是代码上去了,另一位同事去拿最新代码,有可能整个系统都跑不起来。所以,我们还需要一个集成的机器,它负责在每次代码提交之后,去获取最新的代码,然后根据设置去运行相应的测试,看看这次提交的代码有没有什么问题。这样,便可以在下一个同事拿到新代码之前发现问题,并相应的owner去处理,减少更多额外的工作。CruiseControl(由Thoughworks公司开发的,并贡献给开源社区)这个工具便可以做到这一点:它能够监听代码库有没有代码变更,如果有的话,便可以拿到最新代码,然后去运行相应的测试任务。关于CruiseControl的使用,可以看看官网上面的说明,后面可能会独立介绍一下。
  6)Keep the Build Fast  
  前面我们说了,持续集成就是为了更快、及早地发现问题。所以如果一次集成需要耗费几个小时,甚至一天(听说Microsoft一个build就要一天,还是分布式的),那就失去了持续集成的意义了。所以要让每次提交代码触发的集成动作越快越好,XP(极限编程)的大纲说每次build10分钟以内是最理想的。但其实很多时候很难做到的,一个UAT都往往要占据几分钟的时间,重启服务器的时间也是不可或缺的,所以我觉得这个快得根据不同的项目而论。
  7)Test in a Clone of the Production environment  
  测试就是为了检查产品的使用情况,所以集成机器的环境搭建最好是跟最终产品的环境一致,比如说:相同的数据库,相同的服务器,相同的操作系统等等。
  8)Everyone can see what’s happening  
  持续集成就是一种沟通,那我们应该让所有的人实时地、方便地看到持续集成的情况。一种比较简便的办法是安装一个JCCTray(http://jcctray.sourceforge.net/) ,配置响应的参数,启动它之后,可以在桌面的右下方看到一个圆球的图标,当图标是绿色的,说明最近一次的持续集成是成功的,当图标是红色的,说明最近一次的集成是失败的,而当它是黄色的时候,说明持续集成正在进行中。下面的图标显示最近一次的集成是有问题的:


还有一种就是用一盏灯来显示,红绿黄的意思跟上面一样,具体可以看http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Monitor/Devices/BubbleBubbleBuildsInTrouble.rdoc
  9)Automate Deployment  
  当拿到新代码,经过测试,发现没有问题,这时应该进行自动部署。比如自动部署到QA环境等,很多服务器的自动部署都可以用Ant任务来完成的,所以具体的服务器得去查看相应的Ant任务。

    前面按照Martin Fowler的思路,介绍了持续集成的整个过程。个人觉得持续集成不仅仅在Agile是必须的,在传统的开发模式中,有了持续集成,也是对整个开发有很多的帮助,特别是提高代码的稳定性和正确性。

    后面应该会陆续就自己在使用持续集成的一些工具过程中的一些想法记录下来。

TAG:

 

评分:0

我来说两句

Open Toolbar