简单地说,持续集成就是快速且高频率地自动构建项目的所有源码,并为项目成员提供丰富的反馈信息。这句话有很多关键的词:
·快速:集成的速度要尽可能地快,开发人员不希望自己的代码提交半天之后才得到反馈。
·高频率:频率越高越好,例如每隔一小时就是个不错的选择,这样问题才能尽早地被反映出来。
·自动:持续集成应该是自动触发并执行的,不应该有手工参与。
·构建:包括编译、测试、审查、打包、部署等工作。
·所有源码:所有团队成员提交到代码库里的最新的源代码。
·反馈:持续集成应该通过各种快捷的方式告诉团队成员最新的集成状态,当集成失败的时候,反馈报告应该尽可能地反映失败的具体细节。
一个典型的持续集成场景是这样的:开发人员对代码做了一些修改,在本地运行构建并确认无误之后,将更改提交到代码库。具有高配置硬件的持续集成服务器每隔30分钟查询代码库一次,发现更新之后,签出所有最新的源代码,然后调用自动化构建工具(如Maven)构建项目,该过程包括编译、测试、审查、打包和部署等。然而不幸的是,另外一名开发人员在这一时间段也提交了代码更改,两处更改导致了某些测试的失败,持续集成服务器基于这些失败的测试创建一个报告,并自动发送给相关开发人员。开发人员收到报告后,立即着手调查原因,并尽快修复。
图11-1形象地展示了整个持续集成的过程。
通过图11-1可知,当持续集成服务器构建项目成功后,还可以自动将项目构件部署到Nexus私服中。
一次完整的集成往往会包括以下6个步骤:
1)持续编译:所有正式的源代码都应该提交到源码控制系统中(如Subversion),持续集成服务器按一定频率检查源码控制系统,如果有新的代码,就触发一次集成,旧的已编译的字节码应当全部清除,然后服务器编译所有最新的源码。
2)持续数据库集成:在很多项目中,源代码不仅仅指Java代码,还包括了数据库SQL脚本,如果单独管理它们,很容易造成与项目其他代码的不一致,并造成混乱。持续集成也应该包括数据库的集成,每次发现新的SQL脚本,就应该清理集成环境的数据库,重新创建表结构,并填入预备的数据。这样就能随时发现脚本的错误,此外,基于这些脚本的测试还能进一步发现其他相关的问题。
图11-1 持续集成流程
3)持续测试:有了JUnit之类的框架,自动化测试就成了可能。编写优良的单元测试并不容易,好的单元测试必须是自动化的、可重复执行的、不依赖于环境的,并且能够自我检查的。除了单元测试,有些项目还会包含一些依赖外部环境的集成测试。所有这些测试都应该在每次集成的时候运行,并且在发生问题的时候能产生具体报告。
4)持续审查:诸如Checkstyle和PMD之类的工具能够帮我们发现代码中的坏味道(Bad Smell),持续集成可以使用这些工具来生成各类报告,如测试覆盖率报告、Checkstyle报告、PMD报告等。这些报告的生成频率可以低一些,如每日生成一次,当审查发现问题的时候,可以给开发人员反馈警告信息。
5)持续部署:有些错误只有在部署后才能被发现,它们往往是具体容器或者环境相关的,自动化部署能够帮助我们尽快发现这类问题。
6)持续反馈:持续集成的最后一步的反馈,通常是一封电子邮件。在重要的时候将正确的信息发送给正确的人。如果开发者一直受到与自己无关的持续集成报告,他慢慢地就会忽略这些报告。基本的规则是:将集成失败报告发送给这次集成相关的代码提交者,项目经理应该收到所有失败报告。
持续集成需要引入额外的硬件设置,特别是对于持续集成服务器来说,性能越高,集成的速度就越快,反馈的速度也就越快。持续集成还要求开发者使用各种工具,如源码控制工具、自动化构建工具、自动化测试工具、持续集成软件等。这一切无疑都增加了开发人员的负担,然而学习并适应这些工具及流程是完全值得的,因为持续集成有着很多好处:
·尽早暴露问题:越早地暴露问题,修复问题代码的成本就越低。持续集成高频率地编译、测试、审查、部署项目代码,能够快速地发现问题并及时反馈。
·减少重复操作:持续集成是完全自动化的,这就避免了大量重复的手工劳动,开发人员不再需要手动地去签出源码,一步步地编译、测试、审查、部署。
·简化项目发布:每日高频率的集成保证了项目随时都是可以部署运行的,如果没有持续集成,项目发布之前将不得不手动地集成,然后花大量精力修复集成问题。
·建立团队信心:一个优良的持续集成环境能让团队随时对项目的状态保持信心,因为项目的大部分问题区域已经由持续集成环境覆盖了。
既然持续集成有那么多优点,现在让我们开始动手架设自己的持续集成环境吧!