持续集成 作者:Martin Fowler 译者:滕云 原文发布时间:2006年5月1日 翻译时间:2012年2月25日 原文链接:http://www.martinfowler.com/articles/continuousIntegration.html (此翻译已获原作者同意) 持续集成(Continuous Integration, CI)是一种软件开发实践,在实践中项目成员频繁地进行集成,通常每个成员每天都会做集成工作,如此,每天整个项目将会有多次集成。每次集成后都会通过自动化构建(包括测试)来尽快发现其中的错误。许多团队都发现这种方法大大地减少了集成问题并且能够快速地开发出高内聚性的软件。本文简要地总结了持续集成技术及其现状。 我还清楚地记得我刚加入一个大型软件项目时的情形,那时我正在英国一个电子公司做暑期实习。我的经理(属于QA部门)领我参观了一个巨大并很压抑的房间,里面全是格子间。经理告诉我这个项目已经开发了有些年头,现在正在做集成,并且已经集成了好几个月了。经理还告诉我说,没有人真正知道完成集成工作需要多少时间。由此我学到了软件项目的一个通病:软件集成是一个漫长并且无法预测的过程。 然而,软件集成不必像这样的。在ThoughtWorks的大多数项目还有世界上许多其它组织的软件项目中,软件集成并不是什么难事。每个开发人员离共享的工程状态只有咫尺之遥,并且可以在几分钟之内将自己的代码集成进去。任何集成错误都能被快速地发现并得到快速的修正。 这种鲜明的对比并不是源自于后者有多么昂贵或复杂的工具,而关键在于每人都频繁集成这种简单实践,通常是每天向一个被管控的代码库集成。 当我向人们阐述这种实践时,通常得到两种反应:“(在我们这里)行不通”和“无关紧要”。当人们尝试了这种实践之后,他们发现其实做起来比说起来简单,而且这样的实践对于开发“至关重要”。因此有了第三种反应:“是的,我们就是这么做的,不然该怎么活啊?” “持续集成”源自于极限编程(XP),并且是XP最初的12种实践之一。当我以咨询师的角色加入ThoughtWorks时,我鼓励我的团队使用这种技术。Matthew Foemmel将我的建议变成了实实在在的行动,由此软件集成从少有发生并且复杂的状态变成了一桩易事。Matthew和我将我们的经验写在了本文的第一版中,而本文也是我的个人网站上最受欢迎的文章之一。 虽然持续集成并不需要使用特别的工具来部署,但是我们发现拥有一台持续集成服务器将大有益处,其中最著名的有开源的CruiseControl,该软件最初由ThoughtWorks的几个员工开发,现在由一个很大的社区维护着。后来几款其它的持续集成服务器也相继出现了,有开源的,也有商业化的,包括ThoughtWorks Studios的Cruise。 在开发中使用持续集成 对于我来说,解释持续集成及其工作原理最简单的方法便是以一个小的软件功能的开发为例来进行演示。假设我们需要向软件添加一点功能,至于是什么样的功能并不重要,我们假定它很小并且可以在几个小时内完成。 首先我们需要在本地机器上保留一份当前已经处于集成状态的代码的拷贝。我通过代码管理系统在代码库的主线(mainline)上拉下(check out)一份工作代码拷贝。 上一段文字主要针对使用代码控制系统的人,对于不使用代码控制系统的人来说便是胡言乱语了。因此,我将向后者解释一下。代码控制系统用于将项目所有的代码保存在一个代码库(repository)中,项目当前的状态通常被称为主线。任何时候开发人员都可以从主线上获得一份拷贝到本地机器,这被称为“checking out”。本地机器上的代码拷贝称为“working copy”。(多数时候,实际上你是在更新(update)本地代码到主线状态,实践中它们是一样的效果。) 现在,为了完成软件的功能添加,我对本地代码进行修改,其中既包括修改产品代码,也包括添加自动化测试。持续集成非常看重测试,并且在软件代码本身中达到了测试自动化——我将其称为自测试代码,通常使用流行的XUnit测试框架的一个版本。 当我完成了功能开发(或者在我开发过程的不同阶段),我将在本地开发机上完成自动化构建。构建过程将编译并链接本地代码,然后跑自动化测试。只有当构建和测试都没有错误时,该次构建才能算是好的构建。 有了本地的成功构建,我便可以考虑将我修改的代码提交到代码库了。但是,在我提交之前,其他开发人员可能已经向主线提交了他们的修改,所以首先我需要将他们的修改更新到我本地并且重新构建。如果他人的修改与我的修改有冲突,那么在本地编译或者测试阶段将会发生错误,这种情况下,我需要负责修改本地代码直到与主线代码保持适当同步为止。 当本地代码与主线代码同步之后,我便可以向主线提交自己的修改了,代码库也得以更新。…