内容
简介: 本文将介绍如何利用 Rational Team Concert(RTC)在敏捷开发过程中进行持续集成。详细说明了如何在
RTC 中通过采取一系列的步骤和脚本开发,来保证持续集成过程的连续性和提高整个项目的效率。同时还阐述了每一步可以利用的工具和最佳实践,从而使开发过程更加规范化,高效化。
Rational Team Concert(RTC)是 Jazz 产品中最重要的一个,是一个可以任务分解集成,源代码版本控制,进行自动构建和报告的工具。Jazz
做为 IBM 下一代的软件交付平台,为 RTC 提供了更加协作化,更高效率和无缝链接的可扩展框架。RTC
提供了一系列向导,帮助开发团队,建立自己的开发计划,并根据敏捷开发的过程进行迭代的划分和工作项的跟踪。RTC
也提供了源代码的版本控制功能,让开发人员进行无缝的代码交付的同时,还可以和工作项进行绑定。在源代码控制的基础上,RTC
提供了自动构建的工具,从搭建构建服务器,到日常定期的自动构建,都提供了配置模块。RTC 还提供了丰富的报告体系,从工作计划,工作项,到源代码,自动构建,都有专业的报告限制,帮忙开发团队快速了解项目状态。下图
1 展示了 RTC 相关的主要功能。
图 1. Rational Team Concert 的整体功能概览
在项目敏捷开发中,选择好正确的工具,并根据自己的项目进行自动设计定制,把持续集成的实践经验运用到项目中,会加速项目的开发和测试。
在本文中,将详细介绍如何在 RTC 中进行源代码管理,版本控制,搭建项目的构建服务器,进行脚本的定制配置来自动定时构建版本,将工作项,源代码和构建版本进行自动绑定,在构建版本后进行自动的单元测试,定制各种要求的构建版本,并且得到构建版本报告。
整个过程是一个项目的持续集成过程,开发人员可以自动快速的得到最新代码的构建,并且进行检查和测试,以便最快的得到用户的反馈。每天的改动都可以通过快速构建和自动单元测试来保证完整性和基本正确性,尽可能地开发人员在构建和设计变更上的精力。
源代码管理和版本控制是持续集成的基础。在新项目的起始阶段,项目组首先需要对 stream,workspace
和 component 进行规划,并在开发过程中进行持续的代码版本管理。
Component 是项目源代码存储的基础对象。任何一个项目都可以建立一个或多个 component,并允许随着项目的演进而不断完善。但在实际应用中,我们不建议频繁的进行
component 再划分,这需要所有项目组成员进行工作空间的重新加载和代码整合。因此,合理的 component
划分在项目初期十分重要。以下几点经验供大家参考:尽可能降低 component 间的依赖;预先考虑代码组织结构的可扩展性;集中管理公共代码,避免重复。此外,依据功能独立的
Eclipse 工程来划分 component 也是很好的借鉴,这种方法与实际开发相结合,有益于提高开发效率。
Stream 是一个或多个 component 的存储对象,主要用于工作空间内的工作整合。他类似于其他源码管理系统中的分支概念,一个
Stream 仅存储 component 的一个版本,Team 成员通过 stream 来共享代码的变更并进行统一的版本控制。因此建议一个相对独立的
scrum 项目组创建一个单独的 stream,有益于降低组间依赖,并降低代码管理控制的复杂性。当然,项目组内还可以使用多个
Stream 来进行软件的多版本管理。注意:RTC 对于 Stream 下的 component 删除没有用户权限管理,因此,项目组成员切忌随意操作,在项目组中建议指定一名系统管理员进行此类维护操作。
项目组的每个成员都需要基于 scream 创建自己的私有工作空间,并在工作空间中加载所需要的 component。下图
2 展示了 RTC 代码变更提交和共享的原理。
图 2. RTC 代码变更提交和共享机制
每个成员拥有自己的 Eclipe 本地 workspace,并在此工作空间上进行开发工作。同时,大家还都各自拥有私有的
RTC workspace,用于在 RTC 服务器上进行代码存储。代码 checkin 到 RTC 存储工作空间时,其他组员不会看到代码的变更,只有在
deliver 到 Stream 之后才会共享给他人。
在介绍完以上基本概念之后,再向大家介绍一个 RTC 中很重要的概念:Snapshot。它存储了工作空间中所有
component 的镜像。在持续集成过程中,我们可以通过 Snapshot 进行针对特定构建的代码版本管理。如图
3 所示:
图 3. 构建报告的详细信息
打开某一个日构建,你会看到关于这个构建的时间,代码变更,构建引擎等详细信息。其中,点击 Snapshot
链接,如图 4 所示:
图 4. 特定构建的 Snapshot
图 4 的下半部分展示了此 Snapshot 上所有 component 的镜像信息。如果你想在一个新的
workspace 中管理这个版本,那么点击左上角的 Create a new repository workspace
链接,一个全新的 workspace 就生产了,所有 component 将被自动加载。另外一种方法是通过新
Stream 来进行代码版本的管理,点击 Create a new stream 链接,从而生产新的 stream。前者适用于开发成员本人,通过多个私有
workspace 来达成多版本管理的目的。后者则更适用于整个项目组,或者不同项目组之间通过不同 stream
来进行代码的多版本管理。任何 Snapshot 都可以在浏览构建历史列表时找到。当然,项目组也可以脱离
RTC,通过构建脚本进行实时的源码下载,压缩并进行代码的存储。大家可以根据实际需要选择适合的方法。
在第一部分中,我们了解到每一个 Snapshot 是和一个构建报告关联在一起的。RTC 提供了专门的功能来搭建构建服务器,通过简单的安装和配置,帮忙开发人员快速搭建起来自己的构建环境。在一个项目的构建环境中,允许用户采用不止一个构建引擎和构建脚本来保证提供持续不断的构建功能。RTC
的构建引擎是一个可以用于启动构建脚本,以及收集构建结果的过程。
创建一个新的 RTC 构建首先要求在 RTC 中创建一个构建引擎和一个构建定义。构建引擎是用来定义采用哪一个构建服务器来运行构建的过程。构建定义则是用来设定编译哪些模块的代码,调用哪个
ANT 文件来启动编译,和一些编译过程中的参数设定。当这些都准备好了,构建对于项目而言,就变成一个简单的事情了。
先在 RTC 中新建一个构建引擎,如图 5 所示。新建一个构建引擎的时候,需要填一些配置,其中 ID
是最重要的,这个既用来标示这个引擎,并且可以把构建服务器和构建定义关联起来。根据项目所在的 Team Area
进行浏览选择后,由于并没有先创建构建定义,所以右侧的构建定义可以先不选择。等构建定义创建好后,可以再次编辑构建引擎来进行关联配置。
图 5. 创建新的构建引擎
记下了新的构建引擎的 ID,我们就开始创建新的构建定义。选择新建一个构建定义后,会启动一个向导,其中,我们一定要在一开始选择好
Project Team Area,然后可以选择新建一个构建定义,还是复制一个已有的构建定义,并在其基础之上进行修改。如图
6 所示,其中 ID 是这个构建定义的标示,可以选择用上步创建的构建引擎来支持新的构建定义。
图 6. 构建定义
在构建定义上,通过指定调用项目代码中的 ANT 文件,可以启动整个构建过程。在做完这些初步的配置后,就可以通过在构建服务器上运行一个
RTC 提供的命令行应用把这个构建服务器启动起来。这个应用可以在 RTC 的安装包中找到,或者在 RTC-BuildSystemToolkit-*.zip
这样的工具包中解压得到。命令是在安装目录或者解压目录 buildsystem/buildengine/eclipse
下面的 jbe. 运行命令最简单的一种方式是:
jbe -repository https://localhost:9443/jazz
-engineId default -userId myUser -pass myPass
其中 URL 是 RTC 服务器的连接方式,default 是指构建引擎 ID,后面的两个参数是用来做构建的用户名和密码。这里推荐,在
RTC 服务器中,创建一个专门账户来进行构建管理。RTC 的构建模式,是构建服务器,利用这个账户,登录到
RTC 服务器上,把最新的项目代码拉到自己这里,再根据本地的环境,运行脚本进行构建。
当运行起来这个命令后,可以看到有“Waiting for request”的字样,证明构建服务器已经正确的连接到
RTC 服务器上,并且为构建做好准备。
图 7. 构建服务器状态
同时,在新建的构建引擎后,可以发现构建引擎的状态从 waiting 变成了 idle,再次表明 build
服务器和 RTC 服务器的连接是成功的。通过对构建引擎的状态监控,也可以知道构建服务器的状态。
环境准备好了,就可以进行构建了。手动构建是最基本的一种方式。通过在构建定义上,点击请求构建,就可以触发一次构建过程。选择需要的构建参数,这个过程就会在后台运行。每一个开发人员,做了任何的代码改变和提交,都可以触发新的构建过程,来保证代码的有效性和正确性。申请一个新的构建的过程如图
8、图 9 所示。
图 8. 申请一个新的构建
图 9. 构建申请界面
当构建结束后。RTC 服务器会提供构建结果报告,如图 3 所示。开发人员可以查询到这次构建的详细信息。整个开发过程中,对代码进行构建的次数是没有限制的,通过每次构建,都可以得到当时代码的编译情况,并且可以得到一个可运行的软件版本。在持续集成中,定时的构建更是必不可少。在构建定义上,RTC
支持设置构建计划来定时自动的触发一次构建。
图 10. 定时调用构建定义
开发过程中,不同模块的单元测试用例常常为不同的开发人员所写,每个成员都需要保证自己的代码改动不会使其他开发人员的单元测试失败,为了达到这个目标,可以在使用
RTC 进行自动构建的时候,增加一个构建属性 report,如图 9 所示。当需要产生报告的时候,将 report
的值设为 true,这时 RTC 构建引擎在进行自动构建的时候,会通过 ANT 脚本调用 JUnit 对项目的所有单元测试用例自动进行单元测试,并生成测试报告,这样就可以在最短的时间内发现因为代码改动而产生的问题。此外可以在此基础上将测试覆盖率分析工具
EMMA 和静态代码分析工具 FindBugs 一起集成起来,方便提高代码质量。
为了能在 ANT 脚本中调用 EMMA 生成测试覆盖率报告,需要先将相关的类库文件 emma.jar、emma_ant.jar
下载到本地,并在 ANT 脚本中设置相应的路径并引入 EMMA 任务定义,从而使 ANT 知道这些类库的位置。如清单
1 所示:
清单 1. 在 ANT 中引入 EMMA 任务
<path id="emma.lib" >
<pathelement location="${emma.dir}\emma.jar" />
<pathelement location="${emma.dir}\emma_ant.jar" />
</path>
<taskdef resource="emma_ant.properties" classpathref="emma.lib" />
|
在源代码编译完成后,在需要测试的类中注入 EMMA 字节码。如清单 2.
清单 2. 注入 EMMA 字节码
<target name="instrument" depends="compile">
<emma enabled="yes">
<instr instrpath="${classes.dir}" destdir="${instr.dir}"
metadatafile="${emma.report.dir}\metadata.emma" merge="true">
</instr>
</emma>
</target>
|
然后调用 JUnit 任务进行单元测试,在测试前需要设置正确的 jvmarg。如清单 3 所示。
清单 3. 运行测试用例
<target name="test" depends="instrument">
<junit dir="${classes.dir}" printsummary="on" fork="true" >
<classpath refid="classpath" />
<jvmarg value="-Demma.coverage.out.file=${emma.report.dir}\coverage.emma" />
<jvmarg value="-Demma.coverage.out.merge=true" />
<formatter type="xml" />
<batchtest todir="${junit.report.dir}">
<fileset dir="${classes.dir}">
<include name="**/*Test.*" />
</fileset>
</batchtest>
</junit>
</target>
|
最后生成 EMMA 测试覆盖率报告,ANT 脚本如清单 4 所示。
清单 4. 生成测试覆盖率报告
<target name="coverage_report" depends="test">
<emma enabled="true">
<report sourcepath="${src.dir}" encoding="utf-8">
<fileset dir="${emma.report.dir}">
<include name="*.emma" />
</fileset>
<xml outfile="${emma.report.dir}/coverage_report.xml" />
</report>
</emma>
</target>
|
FindBugs 是一款静态代码分析工具,同样也可以在 ANT 脚本中调用 FindBugs 来生成静态代码分析报告,作为持续集成的一部分。
清单 5. 生成 FindBugs 代码静态分析报告
<path id="findbugs.lib" >
<pathelement location="${findbugs.dir}/lib/findbugs-ant.jar" />
</path>
<taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask"
classpathref="findbugs.lib" />
<target name="findbugs" >
<mkdir dir="${findbugs.report.dir}"/>
<findbugs home="${findbugs.dir}" output="xml"
outputFile="${findbugs.report.dir}/findbugs.xml">
<auxClasspath refid="findbugs.classpath" />
<class location="${bin.dir}" />
</findbugs>
</target>
|
为了方便查阅,可以搭建一个 Hudson 服务器,将 JUnit、EMMA 和 FindBugs 结果通过
Hudson 以 Web 的形式展现出来,利用 Hudson 还可以很方便的了解到整个项目的趋势。如图
11 所示。
图 11. 利用 Hudson 集成展示报告
前面介绍了 RTC 的很多功能,和利用 ANT 进行自动构建的实践,为的是保证持续集成的开发过程顺利的进行。开发人员通过查看报告可以及时了解到每次构建的状态,修正存在的问题,从而保证了整个项目的开发进度和质量。
在 RTC 中,点击构建定义,就可以看到利用这个构建定义做出的构建结果。每一次的构建都有一个唯一的标示就是构建标识,这个标识是每次启动构建时的时间戳,这样就可以保证构建标识是唯一的。在一个构建服务器上,同时只能运行一个构建,这样就有了构建队列,也同时保证了构建的唯一性。在构建结果这里,可以详细的检查到每次构建的状态,开始的时间,运行的时间等详细的信息。
图 12. 构建结果
在每个构建结果上双击,可以打开构建的详细信息,如图 3 所示。选择 Logs,就可以看到这次构建的日志文件,如图
13 所示。点击日志文件,就可以查询到详细的构建过程信息。
图 13. 构建日志文件
同样,在 Hudson 服务器上展示的报告中,点击每一个详细的项目,都可以找到具体的错误和正确的信息。这样的持续集成的过程,帮忙开发人员快速的得到构建,并且为方便的查看报告提供了一个途径。同时加快了开发过程,保证了代码质量。
持续集成是敏捷开发过程中的重要环节,可以帮助项目尽早发现和规避风险,持续提高项目质量。Rational
Team Concert 为在敏捷开发中进行持续集成提供了有力的支持,允许用户对持续集成过程进行定制和扩展,本文介绍了使用
RTC 进行持续集成的步骤和方法,希望可以帮助 RTC 用户在最短的时间内搭建高效的持续集成系统。
学习
获得产品和技术
讨论
|