集成 FindBugs、CheckStyle、Cobertura 与 Rational Team Concert 构建系统
简介
在连续集成软件开发方法中,每种新功能都是单独开发的,然后集成在一起的。在此过程中,每个开发人员需要在静态的分析前端全面地评审代码,然后在一个像 IBM Rational Team Concert™ 这样的系统中报告或跟踪它。编码语言 Java 拥有 400 多种标准的静态分析错误类型。确保每种错误都能在评审过程中得以解决并记下每个缺陷,这项操作可能很枯燥。
将 FindBugs、CheckStyle、Unit Test Coverage Check (Cobertura) 与 Rational Team Concert 相集成,可以缩短项目中编写的代码的评审过程。一些开发人员不知道编码最佳实践。这可能导致性能问题,比如内存泄漏或糟糕的 CPU 利用率。这些类型的问题会由与 Rational Team Concert 集成的工具自动检测,该工具会为这些问题制造缺陷。
该集成提高了代码质量;它非常适合项目及其最终用户。
总体设计和描述
要理解实现细节,可以将 Rational Team Concert 视为一个基础系统。将 Rational Team Concert 视为一个基础系统,这意味着将构建引擎、源代码存储库和通知单系统视为单个单元。如下面的图 1 和图 2 所示,Rational Team Concert 支持通过构建引擎组件,请求在源代码存储库上对配置的步骤执行一次构建。我们想要在这些配置的构建步骤上添加脚本来运行质量保证工具。我们能够以顺序模式或并行模式运行这些工具。因为这些工具彼此独立,所以我喜欢在并行模式下运行它们。对于 Cobertura,它可与构建期间执行的单元测试结合运行,所以它需要与单元测试同时运行。
图 1. 集成模块图

图 2. 工具集成流程图

单个工具的实现和集成细节
FindBugs
FindBugs 是 Bill Pugh 和 David Howemeyer 创建的一个开源程序,用于在 Java 代码中寻找错误。它使用静态分析识别 Java 程序中数百种不同潜在类型的错误。潜在的错误分类为 4 个等级:“恐怖 (scariest)”、“可怕 (scary)”、“麻烦 (troubling)” 和 “担忧 (of concern)”。我们建议在 Maven 内部版本的安装阶段运行此工具。
如何集成 FindBugs 与 Rational Team Concert
- 在项目的构建文件中添加一个 FindBugs 工具条目,它将在项目构建期间运行 FindBugs。清单 1 包含该构建文件的 XML 部分,它将触发 FindBugs 并生成包含 HTML 报告的输出文件。
清单 1. 构建期间的 FindBug 及逐行解释
<tasks> 1 <taskdef resource="net/sf/antcontrib/antcontrib.properties" classpathref="maven.plugin.classpath" /> <mkdir dir="${basedir}/target" /> 2 <property name="findbugs.home" value="${env.FINDBUGS_HOME}" /> 3 <path id="findbugs.lib" > <fileset dir="${findbugs.home}/lib" > <include name="**/*.jar" /> </fileset> </path> 4 <property name="proj.file" value="project.fbp" /> 5 <property name="current.scan" value="target/scan-out.xml" /> 6 <property name="temp.db" value="target/temp-db.xml" /> 7 <property name="report.file" value="target/findbugs-report.html" /> <!-- scan the target code --> 8 <taskdef name="findbugs" classname="edu.umd.cs.findbugs.anttask.FindBugsTask"> <classpath refid="findbugs.lib" /> </taskdef> 9 <findbugs home="${findbugs.home}" projectFile="${proj.file}" excludeFilter="excludes.xml" includeFilter="includes.xml" output="xml" outputFile="${current.scan}" /> <!-- finally generate HTML report off the temporary db --> 10 <taskdef name="convertXmlToText" classname= "edu.umd.cs.findbugs.anttask.ConvertXmlToTextTask"> <classpath refid="findbugs.lib" /> </taskdef> 11 <convertXmlToText home="${findbugs.home}" input="${temp.db}" output="${report.file}" format="html:fancy-hist.xsl" jvmargs="-Djavax.xml.transform.TransformerFactory= org.apache.xalan.processor.TransformerFactoryImpl" /> </tasks>
我们将更详细地查看清单 1。
- 第 1 行:定义任务定义资源,它引用了来自 maven: maven.plugin.classpath 的类路径。
- 第 2 行:定义 FindBugs 主路径,它指向可执行程序和 FindBugs 库。
- 第 3 行:包含来自 FindBugs 主路径的所有 .jar 文件。它们将用在以后的处理中。
- 第 4 行:定义将放置所有项目相关信息的项目文件位置。下一节提供了这个位置的一个示例。
- 第 5 行:将输出 XML 文件位置定义为 scan-out.xml。
- 第 6 行:定义可用于维护错误历史记录的数据库文件。
- 第 7 行:定义报告文件位置。
- 第 8 行:FindBugs 任务定义(声明)。
- 第 9 行:FindBugs 工具执行。
- 第 10 行:报告任务定义(声明)。
- 第 11 行:报告生成。它将数据从 XML 转换为 HTML。
项目文件 (project.fbp
) 应包含来自清单 2 的信息。它列出了所有要扫描的类文件夹、将用来编译这些类的依赖
.jar 文件,以及这些类的源代码目录。
清单 2. project.fbp
的示例
<Project projectName="MyProject"> <Jar>../MyProject/target/classes</Jar> <AuxClasspathEntry>../MyProject/lib/servlet-api-2.5.jar</AuxClasspathEntry> <SrcDir>../MyProject/src</SrcDir> </Project>
- 文件 scan-out.xml 包含在项目上运行的 FindBug 工具的输出。清单 3 是该文件的一个示例。
清单 3. scan-out.xml
的示例
<BugInstance type="URF_UNREAD_PUBLIC_OR_PROTECTED_FIELD" priority="2" abbrev="UrF" category="STYLE"> <Class classname="com.ibm.myproject.task.Process"> <SourceLine classname="com.ibm.myproject.task.Process" start="21" end="57" sourcefile="Process.java" sourcepath="com/ibm/myproject/task/Process.java"/> </Class> <Field classname="com.ibm.myproject.task.Process" name="conn" signature= "Lcom/com/ibm/myproject/task/Connection;" isStatic="false"> <SourceLine classname="com.ibm.myproject.task.Process" sourcefile="MyHTTP.java" sourcepath="com/ibm/myproject/task/Process.java"/> </Field> <SourceLine classname="com.ibm.myproject.task.Process" start="25" end="25" startBytecode="11" endBytecode="11" sourcefile="Process.java" sourcepath= "com/ibm/myproject/task/Process.java"/> </BugInstance>
- 创建一个名为 BugSet.txt 的文本文件,scan-out.xml 中报告的每个错误对应该文件中的一行。使用 XSL 或脚本创建此文件。
- 将每个错误从 BugSet 文本文件转换为 Rational Team Concert WorkItem JSON 格式,并使用 自动通知单功能(下面将解释)将它提交到 Rational Team Concert。
CheckStyle
CheckStyle 是一个静态代码分析工具,可在软件开发中使用它来验证 Java 源代码是否符合编码规则。
如何集成 CheckStyle 与 Rational Team Concert
- 在项目的构建文件中添加一个 CheckStyle 工具条目,它将在项目构建期间运行 CheckStyle。清单 4 是该构建文件的 XML 节,它触发 CheckStyle 并生成输出文件和 HTML 报告。
清单 4. 构建期间的 CheckStyle 及逐行解释
<tasks> 1 <taskdef resource="net/sf/antcontrib/antcontrib.properties" classpathref= "maven.plugin.classpath" /> <mkdir dir="${basedir}/target" /> 2 <property name="checkstyle.home" value="${env.CHECKSTYLE_HOME}" /> 3 <path id="checkstyle.lib" > <fileset dir="${checkstyle.home}" > <include name="**/*.jar" /> </fileset> </path> 4 <property name="config_loc" value="${env.BUILD_SCRIPTS}/common/checkstyle" /> <!-- this is for Eclipse-CS to be able to find excludes.xml --> 5 <property name="target.dir" value="${basedir}/target" /> 6 <property name="scan.xml" value="${target.dir}/scan.xml" /> <taskdef resource="checkstyletask.properties" classpathref="checkstyle.lib"/> <!-- Task: Scan --> 7 <checkstyle config="${config_loc}/myproject-checkStyle-config.xml" classpathref= "checkstyle.lib" failOnViolation="false"> <fileset dir="${env.BUILD_HOME}/myproject/src" includes="**/*.java" /> <formatter type="xml" toFile="${scan.xml}" /> </checkstyle> </tasks>
我们将更详细地查看清单 4。
- 第 1 行:定义任务定义资源,它引用了来自 maven: maven.plugin.classpath 的类路径。
- 第 2 行:定义 CheckStyle 主路径,它指向可执行程序和 CheckStyle 库。
- 第 3 行:包含所有来自 CheckStyle 主路径并将在以后的处理中使用的 .jar 文件。
- 第 4 行:定义我们放置 excludes.xml 等配置文件的配置位置。
- 第 5 行:定义将生成所有输出的目标目录。
- 第 6 行:定义输出 XML 文件位置。在本例中,它为 scan.xml。
- 第 7 行:在定义的源代码文件夹下执行实际扫描。仅选择 Java 文件。以 XML 格式生成输出。在本例中,输出将保存在 scan.xml 中。
- 对于 checkstyle 扫描输出,会生成详细的输出,以便可使用提取的 XSL 转换。清单 5 给出了一个示例 XSL 文件。该示例生成一个包含错误列表的 .txt 文件。
清单 5. 示例 XSL 文件
<?xml version="1.0" encoding="ISO-8859-1"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output method="text" encoding="ISO-8859-1" indent="no" /> <xsl:template match="/"> <!-- we loop over all the files reported --> <xsl:for-each select="checkstyle/file"> <xsl:variable name="fname" select="@name" /> <!-- we then loop over all the errors within the file --> <xsl:for-each select="error"> <xsl:variable name="errtype"> <xsl:choose> <xsl:when test= "@source='com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocMethodCheck'"> Javadoc</xsl:when> <xsl:when test= "@source='com.puppycrawl.tools.checkstyle.checks.javadoc.JavadocStyleCheck'"> Javadoc</xsl:when> <xsl:otherwise>Other</xsl:otherwise> </xsl:choose> </xsl:variable> <xsl:value-of select="$errtype" /><xsl:text> problem(s) in </xsl:text><xsl:value-of select="$fname"/><xsl:text> </xsl:text> </xsl:for-each> </xsl:for-each> </xsl:template> </xsl:stylesheet>
- 将每个错误从 DefectSet 文本文件转换为 Rational Team Concert WorkItem JSON 格式,并使用 自动通知单功能(下面将解释)将它提交到 Rational Team Concert。
Cobertura
Cobertura 是一个开源工具,用于借助代码测试来度量代码覆盖率。它通过检测字节代码来完成此操作。此工具基于 jcoverage,帮助程序员度量其测试的有效性和该测试所覆盖的代码量。
如何集成 Cobertura 与 Rational Team Concert?
在项目的构建文件中添加一个 Cobertura 工具条目,它将在项目构建期间运行 Cobertura。清单 6 是该构建文件的 XML 节,它触发了 Cobertura 并生成了输出文件和 HTML 报告。
清单 6. 构建期间的 Cobertura
<tasks> 1 <taskdef resource="net/sf/antcontrib/antcontrib.properties" classpathref= "maven.plugin.classpath" /> <mkdir dir="${project.build.directory}/coverage"/> 2 <taskdef name="cobertura-report" classname="net.sourceforge.cobertura.ant.ReportTask" classpathref="maven.compile.classpath"/> 3 <cobertura-report datafile="${project.build.directory}/cobertura.ser" format="xml" destdir="${project.build.directory}/coverage/xml"> <fileset dir="${basedir}/../myproject/app1/src"> <include name="**/*.java" /> </fileset> </cobertura-report> </tasks>
我们将更详细地查看清单 6。
- 第 1 行:定义任务定义资源,它引用了来自 maven: maven.plugin.classpath 的类路径。
- 第 2 行:定义 Cobertura 任务。
- 第 3 行:Cobertura XML 报告生成器基于 cobertura.ser 文件而构建,该文件存储了检测数据。
Rational Team Concert 自动通知单生成
- 为文本文件中的每行创建一个 JSON,每行对应一个报告错误。清单 7 是 JSON 模板。
清单 7. Rational Team Concert 缺陷 JSON
{ "dc:title":"[Static Analysis] @BUGSUBJ@", "dc:description":"@BUGSUBJ@<br\/><br\/>This problem was found in build: @BUILDID@.<br\/> <br\/>Please see the FindBugs report attached to the above build for more details;<br\/> 1. in Rational Team Concert client, go to Team Artifacts > My Project > Builds<br\/> 2. find the build definition: @BLDDEFN@, and double click it<br\/> 3. in the Builds view that opens, find a build with the 'Label' value matching the build# above, and double click it<br\/> 4. in the Build Result that opens, go to the 'Downloads' tab, and double click the 'logs' in the list<br\/> 5. now your browser should come up, and you just click the findbugs-myproject.html<br\/>" "rtc_cm:plannedFor": { "_comment":"Specifies 'Development' as planned-for for the ticket", "rdf:resource":"https://myjazzrtc.ibm.com:9000/ccm/oslc/iterations/ _gMAnkOlIEeKwsc_eM5wLCA" }, "rtc_cm:ownedBy": { "_comment":"Specifies 'Developer1' (=_0k3H0MheEeKc1_BomI__Fw) as the owner of the ticket", "rdf:resource":"https://myjazzrtc.ibm.com:9000/ccm/oslc/users/_0k3H0MheEeKc1_BomI__Fw" } }
- 该脚本文件将会读取错误报告文本文件中的每一行,并调用 Rational Team Concert 的 REST API 来创建缺陷。
清单 8 是该脚本的一个示例。
清单 8. Rational Team Concert REST 调用脚本
# put dynamic info in the payload BUGDESC=`cat $QTXT1` BLDDEFN=`grep ^buildDefinitionId= $BUILD_HOME/jazz.properties | awk -F= '{print $2}'` BUILDID=`grep ^buildLabel= $BUILD_HOME/jazz.properties | awk -F= '{print $2}'` sed -e "s%@BUGSUBJ@%$BUGDESC%g" -e "s/@BUILDID@/$BUILDID/g" -e "s/@BLDDEFN@/$BLDDEFN/g" new-defect.json >$PAYLOAD PLSZ=`wc $PAYLOAD | awk '{print $3}'` if [ $PLSZ -lt 1000 ]; then echo "...well, payload seems too small to be valid - please check.." cat $PAYLOAD fi # call the REST API curl -s -D - -k -b $COOKIES -H "Content-Type: application/x-oslc-cm-change-request+ json" -H "Accept: text/xml" -X POST --data-binary @$PAYLOAD $HOST/oslc/contexts/$PROJ/ workitems >$JAZRESP
结束语
FindBugs、Cobertura 和 CheckStyle 是得到了广泛应用的代码质量保证工具。与 Rational Team Concert 的集成可帮助程序员提高质量。由于很容易生成缺陷,所以应避免手动干预和额外的工作。与 Rational Team Concert 的集成可帮助初学编码的人最充分地利用它,因为它使这些人能够高效地进行编码。
相关主题
- 关注 FindBugs WiKi。
- 关注 FindBugs,第 1 部分:提高代码的质量。
- 关注 FindBugs,第 2 部分:编写自定义检测器。
- 关注 CheckStyle WiKi。
- 关注 Cobertura 主页。
- 关注 在 Jazz 构建版本中设置静态分析。
- developerWorks 上的 Rational 专区 提供了面向架构师、开发人员和工程师的资源。
- 免费试用 IBM Rational Team Concert。