求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
  
 
 
     
   
分享到
使用SVN+CruiseControl+ANT实现持续集成
 
作者 shishanyuan,火龙果软件    发布于 2013-11-13
 

一、持续集成概念及CC原理介绍

在前面的文章中,介绍自己当时所在团队的处境(使用.NET开发),一个不到十个人的研发团队在保证正常开发进度同时需要并发支持四、五十个项目问题处理,经常为了程序版本冲突、日常测试版本、发布版本提供等重复枯燥无味的手工劳动,导致团队成员身心俱疲。经历这样痛苦的一段时间,终于忍受不了,通过命令行实现了包括获取、编译、发布过程的集成,大大减轻版本编译的时间,此时还能见到团队成员一边编译程序一边聊天轻松的笑脸,这就坚定了自己持续集成的做法,不过可笑是当时自己对持续集成没有任何的概念,只是当时的状况逼自己走了集成之路。

这个工具在经历半年使用进行了一次升级,提供了更多的选项功能,参见升级版本介绍。另外随着公司业务的发展,2009年自己负责推出一个基于JAVA的产品平台,这个平台中包括了七八个子系统。一个困难就出现在我们面前,为了保持以前每周一次发版,每次编译发布都需要两三个小时,为了摆脱这种困局找了很多资料,学习了很多新的思想,对比了很多工具,最终使用了基于CruiseControl(以下简称CC)实现持续集成。

1. 持续集成概念

对于持续集成(Continuous Integration)这个术语源自 XP(极限编程)的一个最佳实践,随着XP近几年的推广持续集成被大家认可并实践,但持续集成并非 XP 的专利,持续集成完全可以应用在采取非XP 方法的项目里面。持续集成也不是一个新的概念,在这个术语出现之前,日创建(daily build)提供同样的含义,这个典型的代表就是微软,他们每天的工作都开始于每日零点的版本构建。持续集成和日创建主要区别就在于实施的频率上,随着 XP 社区的大师级人物 Martin Fowler等人所著《Continuous Integration》为其正名,持续集成这个术语就越来越多地出现在原来日创建出现的位置。

2. 持续集成优点

在传统开发模式中项目按照模块进行划分,等开发完成后再集成到一起进行测试,这种开发方法在小规模程序开发过程中并没有太大的不足。但随着软件技术的发展,软件规模也在扩大,软件需求越来越复杂,软件已经不能简单地通过划分模块方式来开发,因为很多Bug在项目早期就存在了,如果在最后集成的时候才发现问题,开发者需要在集成阶段花费大量的时间来寻找Bug,由于软件的复杂性,需要花费大量的时间进行定位,甚至有些需要调整底层架构。在这个阶段的除虫会议(bug meetings)特别多,会议的内容基本上都是讨论 bug 是怎么产生的,最后往往发展成为不同模块的负责人互相推诿责任。

持续集成最大的优点是可以避免这种传统模式在集成阶段的除虫会议。持续集成主张项目的开发人员频繁的将他们对源码的修改提交(check in)到一个单一的源码库,并 验证这些改变是否对项目带来了破坏,持续集成包括以下几大要点:

1.访问单一源码库,将所有的源代码保存在单一的地点(源码控制系统), 让所有人都能从这里获取最新的源代码,提倡开发人员频繁提交修改过的代码。

2.支持自动化创建脚本,使创建过程完全自动化,让任何人都可以只输入一条命令或者几次点击就完成系统的创建。

3.测试完全自动化,要求开发人员提供自测试的代码,让任何人都可以只输入一条命令或者几次点击就运行一套完整的系统测试。

4.支持自动化部署,能够按照不同的要求发布到测试、发布服务器,提供测试环境和发布程序包;

5.自动提供集成信息,按照不同情况提供通过邮件、报告等方式提供每次集成结果,并且提供发布平台大家能轻易看到集成的进度和结果

持续集成的关键是完全的自动化,自动读取源代码、编译、测试、部署、信息发布。对于每次成功的创建,要求在这个自动化过程中的每一步都不能出错,而最重要的一步是测试,只有最后通过测试的创建才是成功的创建。

在持续集成里面创建不再只是传统的编译那么简单,创建还应该包括自测试,自测试的代码是开发人员提交源码的时候同时提交的,是针对源码的单元测试,将所有的这些自测试代码整合到一起形成测试集,在所有的最新的源码通过编译之后还必须通过测试集的测试才算是成功的创建。这种测试的主要目的是为了验证创建的正确性,McConnell 称之为“冒烟测试”,在持续集成里面,这叫做集成验收测试Build Verify Test,简称 BVT。BVT 测试是质量的基础,QA 小组不会感受到 BVT 的存在,他们只针对成功的创建进行测试(如功能测试)。

持续集成有一个与直觉相悖的基本要点,那就是“ 经常性的集成比偶尔集成要好”。Martin Fowler 认为对于持续集成来说,集成越频繁,效果越好 ,如果你的集成不是经常进行的(少于每天一次),那么集成就是一件痛苦的事情,如果集成偶尔才进行一次(一周甚至一个月), 等到集成阶段发现bug,然后找原因解决bug,会耗费你大量的时间与精力,而且这种方式有点像传统的集成模式,这违背了持续集成的初衷。

根据 Martin Fowler 的观点,项目 bug 的增加和时间并不是线性增长的关系,而是和时间的平方成正比,两次集成间隔的时间越长,bug 增加的数量越是超过你的预期,解决 bug 付出的工作量也越大,而你越觉得付出的工作量越大,你就越想推迟到以后去集成,企图到最后一次性解决问题,结果 bug 产生的就更多,导致下一次集成的工作量更大,你越感觉到集成的痛苦,就越将集成的时间推后,最后形成恶性循环。

需要注意的是从项目的一开始就引入持续集成可以尽早的发现 bug,但是并不代表持续集成可以帮你抓到所有的 bug。持续集成的排错能力取决于测试技术,众所周知,无法证明已经经过测试的代码就已经找到了所有的错误。

前面列举了持续集成这么多优点,但是创建一个持续集成的环境技术上是比较复杂的,也需要一定的时间,关键是在于持续集成可以“及时”抓到足够多的 bug,从根本上消除传统模式的弊端,这就已经值回它的开销了。

ThoughtWorks 公司开放了其持续集成的工具CC的源代码,持续集成对于大部分开发人员来说就不再只是停留在口头上的漂亮的术语,任何人在掌握了持续集成的基础理论后,都可以使用CC来体会持续集成在项目开发中的巨大威力。

3. 集成框架

下个图描述持续集成的硬件环境,图中包括了一台独立的源码库服务器以及开发人员的终端(同时也是源码库服务器的客户端),出自对性能的考虑,建议CC 在一台独立的服务器上运行。当然你可以将 CC 放在发布服务器上甚至某个开发人员的终端上。

4. CC内部工作架构

下图是CC系统内部工作架构图:

CC主要依赖Build Loop循环构建实现,通过读取Config.xml配置文件信息,在每次轮询中完成源代码的检测、编译,然后把编译的版本发布Web容器中,以此同时把日志信息、发布结果通过RSS、邮件、网站等形式发布给干系人。

4.1. Build Loop

前面在讨论持续集成的时候讲到其最重要的特征之一是自动化,而 CC 的 Build Loop 就是为支持自动化而设计的,Build Loop 也是 CC 的核心。

Build Loop 从字面上理解就是循环创建的意思,CC 提供了一个守护进程( daemon),该进程自动根据配置的时间间隔(也可以指定某个具体时间)读取 CC 配置文件并进行循环创建(build cycle),每次 CC 都会重新加载配置文件(修改了配置文件不用重新启动 CC)。

Build Loop 过程中所做的工作如下:访问源码控制系统,查看是否有代码被修改,如果有,获取源码的新版本,并根据配置对源码进行一次 Build,创建一个日志文件,最后向开发人员通知 build 的结果,活动图如下:

因为 Build Loop 是根据配置文件的内容来进行的,根据上面 BuildLoop 所做的工作,我们可以猜出配置信息主要应该包括:定时创建的时间和源码库的访问信息(检查源码变化情况),创建任务信息(如指定 Ant 文件), 记录日志(创建结果),通知(通知的内容可以定制)。

4.2. CC 插件(Plugin)

CC 设计思想是one-size-fits-all,也 就是CC 是由一个很精小( 但是很强大)的核心( Build Loop)以及一些外部插件组成,这给使用者提供了很大的扩展空间,使用者可以根据需要扩展 CC的功能(提供新的插件),而且 CC 是开源项目,你还可以查看源码并修改CC提供的插件。CC提供了六种不同类型的插件:Listener、Bootstrappe、Modificationset、Schedule、Log以及Publisher,CC 的配置是围绕这些插件展开的,下面对这些插件进行一个简单的介绍:

Listener:用于处理一些项目有关的事件;

Bootstrapper:在 CC 进行创建之前运行,是创建前的准备工作

Modificationset:访问源码控制系统(如 CVS,VSS,ClearCase 等等),查看源码自上一次 Build 之后是否被修改过,并据此决定是否需要进行下一次 Build。

Builder:对项目进行创建,熟悉 ANT 的使用者应该很清楚创建的含义,这里简单提一下,一次典型的创建包括了对项目源码的编译,测试,打包

Schedule:设置轮询时间并且指定使用ANT编译所使用的配置文件地址

Publisher:用于发布创建的结果,可以通过 email 的方式通知开发人员。

二、环境搭建和配置介绍

1. 环境搭建

1.1. 下载及目录介绍

从官方站点http://cruisecontrol.sourceforge.net/download.html下载一份最新的 CC 压缩包,最新的版本号为2.8.4

下载了cruisecontrol-bin-2.8.4.zip 直接解压到E盘下,文件结构如下图:

apache-ant-1.7.0:CC中使用ANT工具

artifacts:CC编译生成发布包

etc:自带容器Jetty对应的配置文件

lib:自带容器Jetty所需要到的Jar包

logs:各项目生成日志存在文件夹

projects:存放各项目文件目录,进行程序的编译

webapps:CC自带应用程序存放目录

cc-config:用于CC环境变量配置

cruisecontrol:主应用程序CC目录

dashboard:用于编译结果发布程序

documentation:CC相关文档

config.xml:用于CC编译配置文件,通过修改配置文件引入不同的插件,执行不同的编译流程

cruisecontrol.bat:在WINDOWS环境下进行启用CC批处理脚本

cruisecontrol.sh:在Linux等环境下启动CC脚本

dashboard-config.xml:Dashboard配置文件

1.2. 运行环境

使用JAVA开发的CC,当然需要运行在JDK下并通过Web容器进行发布,具体要求如下:

CC需要运行在至少JDK 1.4环境中,在环境变量中设置有JAVA_HOME,并把java/bin加入到path中;

CC已经内建集成了ANT,不需要单独引入;

CC可以运行在多种应用服务器中,在自带压缩包中捆绑了一个开源应用服务器,那就是Jetty 6,下面为了尽快建立我们的环境,以下将使用该容器。

1.3. 快速启动CC

运行根目录下批处理文件cruisecontrol.bat,出现如下界面:

运行成功后,我们可以在浏览器输入 http://localhost:8080/cruisecontrol/ 来验证一下结果(采用Jetty默认的设置,端口号为 8080)

如果看到上图结果,恭喜你已经成功启动CC。

另外CC提供了更加人性化结果展示Dashboard界面,在浏览器输入 http://localhost:8080/dashboard/

2. 配置介绍

当CC服务器启动时,会自动检测配置信息中的任务信息,并对其进行校验和初始化,之后所有的工作,都是依据该配置信息进行的。

CC的配置使用了其安装目录下的config.xml文件,我们可以通过文本编辑器打开该配置文件,编辑各种配置信息。配置信息的定义遵循了标准XML文件格式,同时遵循了ANT自动构建配置信息的规则。

2.1. config.xml

<cruisecontrol>
<project name="connectfour">

<!-- 用来访问项目当前创建的状态 file: 指定了状态文件的位置 -->
<listeners>
<currentbuildstatuslistener file="logs/${project.name}/status.txt"/>
</listeners>

<!-- 在 CC 进行创建之前运行,创建前的准备工作 -->
<bootstrappers>
<!-- 从源码控制系统更新本地文件: cvsbootstrappers、vssbootstrappers、svnbootstrapper -->
<antbootstrapper anthome="apache-ant-1.7.0" buildfile="projects/${project.name}/build.xml" target="clean" />
</bootstrappers>

<!-- 检查各个源码控制系统中是否发生变化;quietperiod: 单位为秒 设定等待的时间 -->
<!-- 第一次的取出工作为手动执行 -->
<modificationset quietperiod="30">
<!-- touch any file in connectfour project to trigger a build -->
<filesystem folder="projects/${project.name}"/>
</modificationset>

<!-- 指定了构建的时间间隔 单位为秒-->
<schedule interval="300">
<ant anthome="apache-ant-1.7.0" buildfile="projects/${project.name}/build.xml"/>
</schedule>

<!-- 指定项目日志保存的地点 -->
<log>
<merge dir="projects/${project.name}/target/test-results"/>
</log>

<!-- 在 build loop 结束之后运行,发布 build 的结果 -->
<publishers>
<onsuccess>
<!--用于对创建过程中产生的人工制品进行发布-->
<artifactspublisher dest="artifacts/${project.name}" file="projects/${project.name}/target/${project.name}.jar"/>
</onsuccess>

<!--
mailhost=邮件主机
returnname=发件人
returnaddress=发件地址
defaultsuffix=默认邮件后缀
-->
<htmlemail
charset="UTF-8"
mailhost="test163.com"
defaultsuffix="@xxx.com"
username="xxx@163.com"
password="xxx"
returnname="CruiseControl"
returnaddress="xxx@163.com"
subjectprefix="构建日志"
xsldir="webapps/cruisecontrol/xsl"
css="webapps/cruisecontrol/css/cruisecontrol.css">
<always address="xxx@xxx.com.cn"/>
<failure address="xxx@xxx,yyy@yyy.com.cn"/>
</htmlemail>
</publishers>
</project>
</cruisecontrol>

2.2. build.xml

<!—调用ANT执行集成流程,包括清空目录、编译、休眠、测试、打包 -->
<project name="connectfour" default="all">
<target name="all" depends="clean, compile, sleep, test, jar"/>

<!-- 1. 删除根目录下target 目录-->
<target name="clean">
<delete dir="target" quiet="true" />
</target>

<!-- 2. 编译程序,创建目录并编译程序,编译输出为target/classes目录下-->
<target name="compile">
<mkdir dir="target/classes"/>
<javac srcdir="src" destdir="target/classes"/>
</target>

<!-- 3. 在创建前等待60秒,用于Dashboard观察进程-->
<target name="sleep">
<echo message="Sleeping for a while so you can see the build in the new dashboard" />
<sleep seconds="60" />
</target>

<!-- 4. 进行自动化测试,依赖任务为compile-->
<target name="test" depends="compile">
<mkdir dir="target/test-classes"/>
<!—调用junit进行自动化测试-->
<javac srcdir="test" destdir="target/test-classes">
<classpath>
<pathelement location="target/classes"/>
<pathelement location="lib/junit.jar"/>
</classpath>
</javac>

<!—创建测试结果存放目录-->
<mkdir dir="target/test-results"/>
<junit haltonfailure="no" printsummary="on">
<classpath >
<pathelement location="target/classes"/>
<pathelement location="lib/junit.jar"/>
<pathelement location="target/test-classes"/>
</classpath>
<formatter type="brief" usefile="false"/>
<formatter type="xml" />

<!—测试文件所在文件地址-->
<batchtest todir="target/test-results" >
<fileset dir="target/test-classes" includes="**/*Test.class"/>
</batchtest>
</junit>
</target>

<!-- 5. 程序打包,依赖与compile任务-->
<target name="jar" depends="compile">
<jar jarfile="target/connectfour.jar" basedir="target/classes"/>
</target>
</project>

2.3. 执行配置解析

一个持续集成项目是从project节点开始的,对该项目进行的操作都会作为子节点存在与该根节点之下。对于每一个project节点,CC系统都会将其当作一个处理单元,并在最初建立该项目的时候进行初始化操作。

name是project节点常用的属性,也是必设且值唯一的属性,该属性的值会在整个CC系统使用,包括配置文件的${project.name}变量值。

在一个项目节点中,我们可以定义监听器、本地目录位置、变更轮询目录位置、轮询间隔、任务执行、单元测试、日志记录等多种项目操作,同时CC系统支持插件扩展功能,这些扩展插件可以直接在一个项目中使用。

2.3.1. 轮询版本控制系统

版本库轮询机制是使用modificationset进行配置的。CC系统内置的轮询模块会根据设定的时间段对版本库进行检测,一旦发现版本库发生变更,就会调用Check Out Build Test Publish等一系列的操作,对最新的代码进行集成,并运行一系列预先设定的任务。

CC支持十多种版本控制系统,比如CVS、SVN、Starteam、VSS等,对这些版本控制系统的调用,只需要配置相应的节点名称即可。本文以SVN版本管理系统为例。在modificationset节中,我们看到唯一的一个子节点:

<svn localWorkingCopy="projects/CM/${project.name}/src/${project.name}"/>

该节点使用了svn关键字,表示当前工程使用的版本控制系统是SVN,localWorkingCopy属性的值是告诉CC本地的拷贝目录,其余的工作则由CC内置的操作模块进行。

2.3.2. 执行构建脚本

实质上,执行构建脚本也是CC的一个可定制任务,但由于自动构建是持续集成的一个重要组成部分,因此在此单独提出。

CC的自动构建是使用ANT工具来进行的,当然我们也可以使用其它的自动构建工具来替代(比如Maven),这些的工具仅仅是体现在一个任务配置语句上,在此,以ANT工具为例。

在schedule节,我们同样使用了一个子节点来描述自动构建工作:

<ant anthome="ant6" buildfile="projects/CM/${project.name}/src/${project.name}/build.xml"/>

该节点使用了ant关键字,表示该任务使用了ant来进行自动构建任务,anthome属性则指定了ANT工具的具体位置,buildfile属性则指定了ANT进行自动构建所使用的配置文件Build.xml文件的路径。

这样,在CC决定进行自动构建任务时,会根据设定找到执行所使用到的信息。

2.3.3. 执行单元测试

CC可以自动侦测自动构建配置文件中单元测试的任务,并在代码集成完毕将执行结果反馈到相应的模块。
ANT支持xUnit系列的单元测试框架,只需要在配置文件中加入一个target节,即可在自动构建完成之后,进行单元测试工作,有关的详细配置,请参阅ANT官方文档。

三、构建操作及监视

在上一节中我们介绍了环境搭建和配置介绍,并快速启动CC查看集成结果,在本节中我们将详细介绍CC构建操作及监视。

1. 启动CC服务器

通过执行其根目录下的cruisecontrol.bat文件来启动CC。控制台显示“BuildQueue - BuildQueue started”,则说明CC服务器已成功启动。

在启动服务器之前,我们可以打开cruisecontrol.bat文件并修改倒数第三行相应功能的端口数值来指定服务器占用的系统端口,在本例中我们将默认8080端口。

2. Report管理方式

在前一节中介绍CC有两个入口可以管理集成项目,其中CC较早之前提供了Report方式控制主界面,通过http://localhost:8080/cruisecontrol/ 进入,界面如下:

在列表中显示了各个项目的相关信息,包括当前状态、上次失败时间、上次成功时间、构建次数等信息,同时Build按钮可以让CC立即检测工程状态。 点击相应工程名称,则可以进入该工程的详细页面首页,首页清晰明了,主要包括了构建历史信息、最近构建结果、最近构建版本信息等,该页面可以让我们对当前工程的集成信息一目了然,便于我们对不同的集成结果做出相应的处理。页面上部的导航按钮可以让我们进入不同信息的查看界面,包括构建结果、测试结果、XML详细日志文件、状态统计、应用配置、控制台配置等信息。这些导航按钮根据工程设置的不同扩展任务而有所不同。

2.1. 构建结果

在第一个tag页上最上方显示的是该项目最新构建的基本信息(包括构建日期、时间、项目文件最近修改时间)、编译中的警告和错误、自动化测试结果以及本次项目变化具体的明细。

2.2. 测试结果

该tag页显示了自动化测试结果,该结果按照测试类分类,在每个测试类下显示了每一个方法的测试结果以及用时。每一个测试类中都有控制台输出日志,点击进入”system.out” 可以查看具体日志信息。

2.3. XML详细日志文件

记录该项目所有构建信息,如下图所示。

在该文件中记录了项目的基本信息、最后构建时间、最后成功构建时间、构建时间等信息,另外也包括项目配置信息,如JDK版本、构建操作系统等。

2.4. 状态统计

该tag页面通过不同类型图形显示了项目构建状态信息,在tag页面上方显示了页面总构建次数、成功次数和失败次数,接下来通过饼图显示成功与失败次数对比等统计信息。

2.5. 应用配置

CC支持在页面是配置Config.xml文件,首先可以通过“Reload from server”加载该应用的配置信息,配置内容包括Listeners、bootstrappers、Source Controls、Schedule、Log、Publishers等节点,修改完毕后点击“OK”按钮保存配置信息。

2.6. 控制台配置

在该tag页中可以对该项目控制进行配置,具体包括构建轮询时间、版本标签号、发布包命名格式等信息。

3. Dashboard管理方式

我们现在比较常用的(也是CC推荐)是通过Dashboard界面来管理项目集成,其地址为 http://localhost:8080/dashboard。该方式以不同颜色的色块表示不同项目构建的状态,能够直观地观察到不同项目当前状态,当把鼠标放在小方块上时,会显示该项目的主要信息。在页面的右边显示了构建项目的状态统计,能够了解构建概况。另外几个小工具,提供了RSS连接以及更加人性化页面配置工具。

在介绍Dashboard之前我们熟悉CC中项目的状态, CC把项目分成三类,Discontinued(停止),Inactive(不活动),及Active(活动)。

Discontinued(停止)表示CC可以找到该项目的日志文件,但在配置文件(Config.xml)中并没有该文件。所以CC不会去构建它,但你可以看到这个项目过去构建的历史信息。如果想把这个项目从CC中删除,只有把该项目的日志目录删除才行。如果该项目名为"petclinic",目录当该是${CruiseContor.Home}/logs/petclinic。

Inactive(不活动)表示CC在配置文件(Config.xml)中发现了该项目,但是没有发现关于这个项目的任何历史信息,即在CC的日志目录中还没有该项目的日志文件,或日志文件被人为删除了。CC会根据配置信息对这个项目进行检查新版本并进行构建,当第一次构建完成后,CC就会生成日志,这个项目状态就会转为Active了

Active(活动)表示CC即可以找到该项目的日志文件,又在配置文件(Config.xml)中可以发现它。此时,这个项目可能是构建成功,也可能是构建失败,还可能是构建中。

Dashboard主要有四个tag页面,它们分别是Dashboard,Builds,Build Details和Administatiorn。

3.1. Dashboard

在Dashboard tab页面左边可看到所有项目的状态,不同颜色色块表示不同的构建状态

红色方块表示该项目最近一次构建是失败的

绿色方块表示该项目最近一次构建是成功的

灰色方块表示该项目可能是Inactive的,也可能是Discontinued。

另外在页面的右边看以看到对所有构建项目的统计信息,不同图标、数目表示所处不同状态项目的个数。

3.2. Builds

在该tab页面左中部显示了所有构建项目状态统计信息,右中部则是不同工具的链接,页面底部以列表方式展示了所有项目构建信息。

在每一笔构建信息中点击可以看到所有构建,点击图标可以查看所有成功构建。如果你将Force Build配置为true,在列表右侧有一个按钮,点击该图标可以强迫该项目进行构建,而不必等到其下一次检查,也不必等到它有版本变化。点击后在Builds页面和Dashboard页面可以看到正在构建图标。

另外可以通过有工具图标进行该项目RSS和JMX控制台配置,其操作见Report管理方式1.2.6部分

3.3. Build Details

此tab页面会列出该项目某次构建的详细信息,包括项目文件最近修改记录、构建日志、自动化测试结果、构建警告和错误,如果构建成功的话,在配置文件(config.xml)中配置的Artifacts也会在名为Artifacts的tab页上看到。

右侧的列表是该项目所有历史构建列表,点击其中一个构建,你就可以得到该次构建的详细信息。

3.4. Administration

该页面你可以看到About和Configuration两个子标签。

在About子标签中,你可以看到CC所用的环境信息,如CC的版本号、所用的操作系统和JDK版本等。

在Administration子标签中,你可以看到CC的Dashboard-config.xml文件内容。

相关文章

为什么要做持续部署?
剖析“持续交付”:五个核心实践
集成与构建指南
持续集成工具的选择-装载
相关文档

持续集成介绍
使用Hudson持续集成
持续集成之-依赖管理
IPD集成产品开发管理
相关课程

配置管理、日构建与持续集成
软件架构设计方法、案例与实践
单元测试、重构及持续集成
基于Android的单元、性能测试
 
分享到
 
 


集成与构建指南
项目管理:Maven让事情变得简单
持续集成工具hudson
持续集成
Maven权威指南
程序集(UML中的包)之间循环
更多...   


产品发布管理
配置管理方法、实践、工具
多层次集成配置管理
使用CC与CQ进行项目实践
CVS与配置管理
Subversion管理员


海航股份 重构及持续集成
电研华源 设计原理、建模与重构
软件配置管理日构建及持续集成
单元测试、重构及持续集成
中国软件研发中心 单元测试与重构
单元测试、重构和持续集成实践
罗克韦尔 C++单元测试+重构+Gtest
更多...