Martin Fowler 的持续集成(4)

发表于:2012-12-21来源:博客园作者:无知者云点击数: 标签:持续集成
如果第二阶段构建发现了bug,通常意味着应该在第一阶段中引入新的测试来予以保证。 当然,以上的两阶段构建只是一个例子,你完全可以加入多个构建

  如果第二阶段构建发现了bug,通常意味着应该在第一阶段中引入新的测试来予以保证。

  当然,以上的两阶段构建只是一个例子,你完全可以加入多个构建阶段。提交构建之后的其它构建是可以并行完成的,如果这些阶段的构建需要好几个小时,那么可以用几台机器来并行完成。通过这种并行化,你可以将提交构建之外的所有测试都引入到构建过程中来,比如性能测试。

  在与生产环境的拷贝环境中运行测试

  测试旨在发现可能在生产环境中出现的问题,因此如果你的测试环境与生产环境不同,那么测试很有可能发现不了生产环境中的bug。

  因此,你的测试环境应该尽量与生成环境相同。使用相同的数据库,相同的操作系统,并且版本都应该一样。另外,将生产环境中的库文件也放到测试环境中,即使构建时用不到这些库。IP地址和端口号也应当相同,当然还包括硬件。

  但事实上这是有限制的。如果你开发的是桌面软件,很难预测你的客户在使用哪些第三方库。再者,生产环境可能非常昂贵。即便存在这么多限制,你依然应当尽量去复制生产环境,并熟知因测试环境和生产环境的不同而可能导致的风险。

  如果你搭建的环境足够简单并没有多少烦人的外部交互,那么你的提交构建便可在仿真环境中进行。但是,由于系统反应慢等原因,你可能需要test doubles。因此,通常情况是在人工环境下跑提交构建以获取速度,而用一个生产环境的拷贝环境来跑其它测试。

  我注意到,虚拟化技术越来越引起人们的兴趣。由于虚拟机可以保存构建所需的所有东西,故在虚拟机中运行构建和测试相对比较容易。另外,虚拟机技术也允许你在一台机器上运行多个测试,或者可以模拟多台机器同时访问网络的情况。随着虚拟机性能逐渐提升,它将引起更多的注意。

  使任何人都能轻易获得可执行文件

  软件开发最困能的事情之一便是你不能保证所开发的是正确的软件。我们发现人们往往很难预知自己究竟想要什么,而相反,对已有的东西进行评判和修改却容易的多。敏捷开发过程则恰恰是符合人类这种行为习惯的。

  为此,项目中的所有成员都应能够获得最新的可执行文件并能成功的运行,目的可以包括做演示,浏览测试或者仅仅看看项目本周有何修改。

  这是很容易达到的:确保一个通用的地方来存放最新可执行文件。在同一个地方存放多个可执行文件也是很有用的。对于最新的可执行文件,应当保证能够通过提交测试。

  如果你的开发过程有一个很好的迭代计划,将每次迭代最后一次构建生成的可执行文件存放起来也是明智的做法。

  人人都能看到正在发生什么

  持续集成主要在于交流,因此应当保证每人都能轻易看到当前系统的状态和已做的修改。

  主线的构建状态是非常重要的,Cruise服务器包含一个网站,你可以在该网站上看到当前的构建状态和最后一次主线构建的结果,许多团队喜欢用比较显眼的标识来反应构建状态,比如在屏幕上放一盏灯,灯绿表示构建成功,灯红表示失败。尤其常见的是lava lamps——不仅表明构建状态,还可显示构建时间。如果红灯中有了气泡,则表明构建已经失败了很长一段时间了。每个团队都有自己的选择,当然,适合自己的才是最好的。

  对于手工完成的持续集成过程,这种可见性也是很重要的,构建机器的显示器应该能显示主线构建的状态。通常,正在做集成的人会放一个token在桌上来表明他正在做集成。人们喜欢在构建成功后播放一些简单的声音,比如闹铃之类的。

  当然,CI服务器的网站可以展示更多的信息。Cruise不但能可以显示是谁在构建,并且能显示最新提交的修改。另外,Cruise还可以查看提交历史,这样,团队成员便可以很清楚项目的进展情况。据我所知,有些团队的头便是通过这种方式来了解项目成员的工作情况和整个系统的修改情况。

  使用CI网站的另一个好处是,哪怕不在一起工作的人都可以看到当前项目的状态。再者,你也可以将不同项目的构建信息放到一起。

  并不是只有CI网站才能展示显示构建信息。由于构建的不稳定性是一直存在的,这时我们可以将全年的日历画在一张墙上,每天对应一个方块,如果构建成功,QA则在该天的方块贴上绿色标签,否则贴上红色标签。时间一久,这份日历便可显示出项目的稳定性进展情况。

  自动化部署

  做持续集成需要多种环境,不同的构建阶段需要不同的环境。每天,项目的可执行文件都会在这些环境之间搬来移去,于是你希望将这些过程自动化。因此,自动化部署脚本便很重要了,不仅包括测试环境的脚本,也包括针对生产环境的部署脚本。虽然我们不是每天都向生产环境部署,但自动化部署不仅可以加速部署过程,并且能够减少部署错误。

  如果你已经有了生产环境的自动化部署,那么也应该考虑一下相应的自动化回滚。由于失败是时而会发生的事情,在这种情况下,我们希望能快速回滚到失败之前的状态。这样一来,我们在部署是也不用那么畏首畏尾了,于是我们可以频繁的发布软件,用户亦能尽快的享受到新的功能。(Ruby on Rails社区有一款名为Capistrano的工具即是一个典型的例子。)

  在集群环境中,我看到有每次只向一个节点部署的情况,由此在几个小时之内逐渐完成所有节点的部署。

  对于一些面向大众的web应用,我所了解的另外一种很有趣的部署方式是,先试验性针对一部分用户进行部署,再通过这些用户的试用情况来决定是否向所有用户部署。自动化部署,做为CI的一项原则,能够很好的胜任这些工作。

  持续集成的好处

  总的来说,我认为持续集成的最大好处在于降低风险。我又想起了我在本文一开始提到的那个项目——已经处于项目的末期,但是仍然不知到何时才能结束。

  延期集成的缺点在于,很难预测集成到底要花多少时间,更糟的是,你很难了解集成的进展情况。

  持续集成正好解决了这些问题。每次集成的时间都不长,任何时候你都知道自己所处的情况,软件的哪些地方在工作,哪些没有。

  Bug——恶心的玩意儿,伤害我们的自信,搅乱我们的日程,还破坏我们的名声。如果在生产环境中遇到了bug,那么用户将会把气往你身上撒。而在开发环境中,bug拦着你的路,迫使你无法完成余下的工作。

原文转自:http://www.ltesting.net