NetBeans创建Web项目缺省是以Ant为基础进行构建,可以自动生成基本的编译,打包等Ant脚本,省去了手工编辑的繁琐,另外预留了一些Ant任务可供覆写和扩展,本文的目的是在NetBeans生成的Ant脚本基础上进行扩展,以实现一个完整的自动构建集成测试过程。
一、环境准备
一、环境准备
- NetBeans 6.1
- 测试所需的jar包:
asm-2.2.1.jar
asm-tree-2.2.1.jar
cobertura.jar
commons-codec-1.3.jar
commons-collections.jar
commons-httpclient-3.1.jar
commons-io-1.3.1.jar
commons-lang-2.3.jar
cssparser-0.9.4.jar
dom4j-1.6.1.jar
hamcrest-core-1.1.jar
hamcrest-library-1.1.jar
htmlunit-1.14.jar
jaxen-1.1.1.jar
jdom-1.0.jar
jmock-2.4.0.jar
js-1.6R7.jar
junit-3.8.2.jar
jwebunit-core-1.4.1.jar
jwebunit-htmlunit-plugin-1.4.1.jar
nekohtml-0.9.5.jar
pmd-4.2.1.jar
regexp-1.3.jar
servlet-api.jar
strutstest-2.1.4.jar
xercesImpl-2.6.2.jar
xml-apis-1.3.02.jar
xmlParserAPIs-2.6.2.jar
xom-1.0.jar - Ant 1.7.0,此外需要activation.jar,commons-net-1.4.1.jar,jakarta-oro-2.0.8.jar,mail.jar。将以上jar包拷贝到ANT_HOME/lib目录下,设置路径加入ANT_HOME/bin,还有环境变量ANT_OPTS=-Xms512m -Xmx1024m
- 一台远程部署服务器,安装Tomcat 6.0.16和Apache Httpd 2.2.8
- 在NetBeans中创建一个Web工程,使用strutsTest和JMock编写单元测试,JWebUnit编写端对端测试,编译打包通过。
- 远程部署
<property file="build.properties" />
<!-- 覆写-post-dist任务,加构建版本号和时间 -->
<target name="-post-dist" description="Record build information">
<propertyfile file="build.info">
<entry default="0001" key="build.number" operation="+" pattern="0000" type="int" />
<entry default="now" key="build.time" pattern="yyyy.MM.dd HH:mm:ss" type="date" />
</propertyfile>
<copy file="build.info" tofile="${dist.dir}/build.info" />
<ftp server="${ftp.server}"
remotedir="${ftp.remotedir}"
userid="${ftp.user}"
password="${ftp.password}"
depends="true"
binary="true"
verbose="true"
ignorenoncriticalerrors="true">
<fileset dir="${dist.dir}" />
</ftp>
</target>
<!-- 取消远程部署的旧版本应用 -->
<target name="remove-remote-app" >
<property name="status.file" location="deploy-${tomcat.server}.txt" />
<get src="${tomcat.manager.url}/remove?path=/${webapp.name}"
dest="${status.file}"
username="${tomcat.username}"
password="${tomcat.password}" />
<loadfile property="deploy.result" srcfile="${status.file}" />
<echo>${deploy.result}</echo>
</target>
<!-- 部署新版本 -->
<target name="deploy-remote-server" depends="clean,dist,remove-remote-app">
<property name="install.file" location="deploy-remote-install.txt" />
<property name="redist.url" value="file://${target.dir}" />
<property name="target.url" value="path=/${webapp.name}&war=${redist.url}" />
<get src="${tomcat.manager.url}/install?${target.url}"
dest="${install.file}"
username="${tomcat.username}"
password="${tomcat.password}" />
<loadfile property="deploy.remote.result" srcfile="${install.file}" />
<echo>${deploy.remote.result}</echo>
</target>
build.properties为新建的资源文件,内容如下:
reports.dir=build/test/results
reports.xml.dir=${reports.dir}
reports.html.dir=${reports.dir}/junit-html
coverage.xml.dir=${reports.dir}/cobertura-xml
coverage.html.dir=${reports.dir}/cobertura-html
pmd.html.dir=${reports.dir}/pmd-html
instrumented.dir=${reports.dir}/cobertura-inmt
smtp.hostname=10.100.1.16
smtp.hostport=25
mail.user=xxxx
mail.password=xxxx
smtp.from=xxxx@xxxx.cn
smtp.tolist=xxxx@xxxx.cn
ftp.server=10.100.1.156
ftp.remotedir=dist
ftp.reportdir.junit=/home/httpd/html/htdocs/hosptest/junitreport
ftp.reportdir.cobertura=/home/httpd/html/htdocs/hosptest/coberturareport
ftp.reportdir.pmd=/home/httpd/html/htdocs/hosptest/pmdreport
ftp.user=deployer
ftp.password=deployer
tomcat.server=10.100.1.156
tomcat.manager.url=http://${tomcat.server}:8080/manager
tomcat.username=system
tomcat.password=manager
webapp.name=hosp
target.dir=/home/deployer/dist/hosp.war
report.url=http://10.100.1.156/hosptest/ - 运行测试,生成JUnit单元测试报告,Cobertura测试覆盖率报告及PMD代码质量检查报告
<!-- 装入Cobertura和PMD插件 -->
<path id="cobertura_classpath">
<fileset dir="lib">
<include name="test/cobertura.jar" />
<include name="test/asm-2.2.1.jar" />
<include name="test/asm-tree-2.2.1.jar" />
<include name="jakarta-oro-2.0.8.jar" />
<include name="log4j-1.2.14.jar" />
</fileset>
</path>
<taskdef classpathref="cobertura_classpath" resource="tasks.properties"/>
<path id="pmd.classpath">
<fileset dir="lib">
<include name="test/pmd-4.2.1.jar" />
<include name="test/asm-2.2.1.jar" />
<include name="test/jaxen-1.1.1.jar" />
</fileset>
</path>
<taskdef name="pmd" classname="net.sourceforge.pmd.ant.PMDTask" classpathref="pmd.classpath"/>
<target name="instrument" depends="init,compile">
<delete file="cobertura.ser"/>
<delete dir="${instrumented.dir}" />
<cobertura-instrument todir="${instrumented.dir}">
<ignore regex="org.apache.log4j.*" />
<fileset dir="${build.classes.dir}">
<include name="**/*.class" />
<exclude name="**/*Test.class" />
</fileset>
</cobertura-instrument>
</target>
<target name="-pre-test-run" depends="init" if="have.tests">
<mkdir dir="${reports.dir}"/>
<mkdir dir="${instrumented.dir}" />
<mkdir dir="${reports.html.dir}" />
<mkdir dir="${coverage.xml.dir}" />
<mkdir dir="${coverage.html.dir}" />
<mkdir dir="${pmd.html.dir}" />
</target>
<target name="coverage-test" depends="init,-pre-test-run,compile-test">
<junit dir="${basedir}" errorproperty="tests.failed" failureproperty="tests.failed" fork="true" jvm="${platform.java}" showoutput="true">
<classpath location="${instrumented.dir}" />
<classpath location="${build.test.classes.dir}" />
<classpath location="${build.classes.dir}" />
<classpath path="${javac.test.classpath}" />
<formatter type="xml" />
<test name="${testcase}" todir="${reports.xml.dir}" if="testcase" />
<batchtest todir="${reports.xml.dir}" unless="testcase">
<fileset dir="${test.src.dir}">
<include name="**/*Test.java" />
<exclude name="com/xued/hosp/jwebunit/*Test.java" />
</fileset>
<fileset dir="${test.src.dir}">
<include name="com/xued/hosp/jwebunit/*Test.java" />
</fileset>
</batchtest>
</junit>
<junitreport todir="${reports.xml.dir}">
<fileset dir="${reports.xml.dir}">
<include name="TEST-*.xml" />
</fileset>
<report format="frames" todir="${reports.html.dir}" />
</junitreport>
</target>
<target name="coverage-check">
<cobertura-check branchrate="34" totallinerate="100" />
</target>
<target name="coverage-report">
<cobertura-report srcdir="${src.dir}" destdir="${coverage.xml.dir}" format="xml" />
</target>
<target name="alternate-coverage-report">
<cobertura-report destdir="${coverage.html.dir}">
<fileset dir="${src.dir}">
<include name="**/*.java"/>
</fileset>
</cobertura-report>
</target>
<!-- 运行所有测试,包括JUnit单元测试和JWebUnit端对端测试,生成测试报告 -->
<target name="coverage" depends="instrument,coverage-test,coverage-report,alternate-coverage-report" />
<!-- 运行PMD,生成代码质量报告 -->
<target name="pmd">
<pmd shortFilenames="true" classpath="." rulesetfiles="conf/pmd.xml">
<formatter type="html" toFile="${pmd.html.dir}/index.html" linkPrefix="http://pmd.sourceforge.net/xref/"/>
<fileset dir="src/java">
<include name="**/*.java"/>
</fileset>
</pmd>
</target>
pmd.xml指定了代码检查的规则集:
<?xml version="1.0" encoding="UTF-8"?>
<ruleset name="Custom ruleset"
xmlns="http://pmd.sf.net/ruleset/1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
<rule ref="rulesets/basic.xml"/>
<rule ref="rulesets/braces.xml"/>
<rule ref="rulesets/controversial.xml">
<exclude name="OnlyOneReturn" />
<exclude name="DataflowAnomalyAnalysis" />
<exclude name="AvoidFinalLocalVariable" />
</rule>
<rule ref="rulesets/codesize.xml/ExcessiveMethodLength"/>
<rule ref="rulesets/codesize.xml/ExcessiveParameterList"/>
<rule ref="rulesets/codesize.xml/CyclomaticComplexity" />
<rule ref="rulesets/design.xml">
<exclude name="ConfusingTernary" />
<exclude name="UncommentedEmptyConstructor" />
</rule>
<rule ref="rulesets/imports.xml"/>
<rule ref="rulesets/naming.xml"/>
<rule ref="rulesets/optimizations.xml">
<exclude name="MethodArgumentCouldBeFinal" />
<exclude name="LocalVariableCouldBeFinal" />
<exclude name="UseStringBufferForStringAppends" />
</rule>
<rule ref="rulesets/strictexception.xml">
<exclude name="SignatureDeclareThrowsException" />
</rule>
<rule ref="rulesets/strings.xml"/>
<rule ref="rulesets/typeresolution.xml">
<exclude name="SignatureDeclareThrowsException" />
</rule>
<rule ref="rulesets/unusedcode.xml"/>
</ruleset> - 将测试报告上传,并且发送Email
<!-- 删除旧的远程文件 -->
<target name="clean-remote-report">
<ftp server="${ftp.server}"
remotedir="${ftp.reportdir.junit}"
userid="${ftp.user}"
password="${ftp.password}"
action="del"
depends="true"
binary="true"
verbose="true"
ignorenoncriticalerrors="true">
<fileset includes="**/*" />
</ftp>
<ftp server="${ftp.server}"
remotedir="${ftp.reportdir.cobertura}"
userid="${ftp.user}"
password="${ftp.password}"
action="del"
depends="true"
binary="true"
verbose="true"
ignorenoncriticalerrors="true">
<fileset includes="**/*" />
</ftp>
<ftp server="${ftp.server}"
remotedir="${ftp.reportdir.pmd}"
userid="${ftp.user}"
password="${ftp.password}"
action="del"
depends="true"
binary="true"
verbose="true"
ignorenoncriticalerrors="true">
<fileset includes="**/*" />
</ftp>
</target>
<!-- 上传新的远程文件 -->
<target name="ftp-report" depends="clean-remote-report">
<ftp server="${ftp.server}"
remotedir="${ftp.reportdir.junit}"
userid="${ftp.user}"
password="${ftp.password}"
depends="true"
binary="true"
verbose="true"
ignorenoncriticalerrors="true">
<fileset dir="${reports.html.dir}" />
</ftp>
<ftp server="${ftp.server}"
remotedir="${ftp.reportdir.cobertura}"
userid="${ftp.user}"
password="${ftp.password}"
depends="true"
binary="true"
verbose="true"
ignorenoncriticalerrors="true">
<fileset dir="${coverage.html.dir}" />
</ftp>
<ftp server="${ftp.server}"
remotedir="${ftp.reportdir.pmd}"
userid="${ftp.user}"
password="${ftp.password}"
depends="true"
binary="true"
verbose="true"
ignorenoncriticalerrors="true">
<fileset dir="${pmd.html.dir}" />
</ftp>
</target>
<!-- 发送Email -->
<target name="notifyteam" depends="ftp-report">
<property file="build.info" />
<mail mailhost="${smtp.hostname}"
mailport="${smtp.hostport}"
user="${mail.user}"
password="${mail.password}"
subject="Test build #${build.number}"
from="${smtp.from}" tolist="${smtp.tolist}" messagemimetype="text/html">
<message>The build #${build.number} is now available.Please browse ${report.url} to see reports</message>
</mail>
</target> - 将所有任务集成
<target name="intergrate" depends="deploy-remote-server,coverage,pmd,notifyteam"/>
- 在命令行下输入ant intergrate即可完成所有任务,将此命令定制成自动执行脚本,即可实现自动集成。
没有评论:
发表评论