软件集成并不是一个新的问题或者概念,当一个人独立开发一个产品的时候,比如做毕业设计的时候,根本就不存在软件集成,更不用去考虑持续集成!可到了三五个人、七八条枪,进行团队开发的时候,这个问题就不得不去考虑了!特别是在传统的瀑布式开发中,模块开发是独立进行,当各个模块都完整开发完了之后,再进行模块间的整合,很多噩梦都发生在这个时候:接口不统一,模块间对需求的理解不一致
……
往往要磨上十天半个月才能搞定!
Martin Fowler (
ThoughtWorks
公司的那个“大胡子”)对持续集成的注解如下:
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
一般来说,工程都是以团队的形式进行开发的。一个工程的文件都是以千百计算的,如果需要手工去跟踪、同步这些文件,那无疑是天方夜谭。于是源代码管理工具应运而生。开源的源代码管理工具有 CSV ,
Subversion
等,个人感觉
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 Development
(
TDD
,测试驱动开发)
,
先写测试,再写实现!一般来说,测试包括了后台逻辑测试
(
一般用
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
(极限编程)的大纲说每次
build
在
10
分钟以内是最理想的。但其实很多时候很难做到的,一个
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
是必须的,在传统的开发模式中,有了持续集成,也是对整个开发有很多的帮助,特别是提高代码的稳定性和正确性。
后面应该会陆续就自己在使用持续集成的一些工具过程中的一些想法记录下来。
Martin Fowler
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
下面我们按照 Martin Fowler
1)Maintain a Single Source Repository
一般来说,工程都是以团队的形式进行开发的。一个工程的文件都是以千百计算的,如果需要手工去跟踪、同步这些文件,那无疑是天方夜谭。于是源代码管理工具应运而生。开源的源代码管理工具有 CSV
2)Automate the Build
从拿到源代码到变成一个可运行的系统,这中间要经过一个复杂的过程。一个简单的过程大概有:编译 /
3)Make Your Build Self-Testing
在传统的开发模式中,当 build
集成很多时候是为了沟通,告诉其他开发人员自己已经做了那些代码的改动。及时的沟通在团队开发中的重要性是不容置疑的。所以我们要尽快地将自己代码的改动提交。但代码提交之前,一定要确保自己代码的正确性,至少让系统可以跑起来。而不是说代码一有改动,就不管三七二十一,把代码弄上去就行了,这样对整个团队来说, cost
5)Every Commit Should Build the Mainline on an Integration Machine
前面说到每天都提交代码,这就会带来一个问题:在提交代码之前,未必有去拿到最新代码,即使拿到最新代码,由于开发环境的不同,也可能没发现什么问题。于是代码上去了,另一位同事去拿最新代码,有可能整个系统都跑不起来。所以,我们还需要一个集成的机器,它负责在每次代码提交之后,去获取最新的代码,然后根据设置去运行相应的测试,看看这次提交的代码有没有什么问题。这样,便可以在下一个同事拿到新代码之前发现问题,并相应的 owner
前面我们说了,持续集成就是为了更快、及早地发现问题。所以如果一次集成需要耗费几个小时,甚至一天(听说 Microsoft
测试就是为了检查产品的使用情况,所以集成机器的环境搭建最好是跟最终产品的环境一致,比如说:相同的数据库,相同的服务器,相同的操作系统等等。
持续集成就是一种沟通,那我们应该让所有的人实时地、方便地看到持续集成的情况。一种比较简便的办法是安装一个 JCCTray(
还有一种就是用一盏灯来显示,红绿黄的意思跟上面一样,具体可以看 http://www.pragmaticautomation.com/cgi-bin/pragauto.cgi/Monitor/Devices/BubbleBubbleBuildsInTrouble.rdoc
当拿到新代码,经过测试,发现没有问题,这时应该进行自动部署。比如自动部署到 QA
前面按照 Martin Fowler
后面应该会陆续就自己在使用持续集成的一些工具过程中的一些想法记录下来。