cobertura 在websphere中的使用

   关于cobertura的介绍可参考我转载的几篇文章,这里就不做介绍了.这里我想介绍一下cobertura和中间件的结合使用。
    我们的项目是一个J2EE的项目,涉及了spring,hibernate,struts,EJB。部署在websphere上,本地的开发环境是IBM RAD。项目组自己开发了一个基于JUnit的测试框架,可以通过JSP调用测试类得出测试结果。美中不足的是该框架得不到代码覆盖率。于是我们决定引入cobertura.
    分析cobertura自带的example的bulid.xml我们可以将其分解成几个步骤:
   1.编译源代码,该步骤其实IDE已经替我们完成了,不需要通过ant去编译,所以省去.
<target name="compile"  depends="init">
		<javac srcdir="${src.dir}" destdir="${classes.dir}" debug="yes">
			<classpath refid="cobertura.classpath" />
		</javac>
	</target>

   2.instrument,在这里cobertura生成了instrument后的源代码。并生成cobertura.ser信息文件,该文件很重要,包含了需要被测试的类的信息。
    
<target name="instrument" depends="init,compile">
		<!--
			Remove the coverage data file and any old instrumentation.
		-->
		<delete file="cobertura.ser"/>
		<!--<delete dir="${instrumented.dir}" />
-->
		<!--
			Instrument the application classes, writing the
			instrumented classes into ${build.instrumented.dir}.
		-->
		<cobertura-instrument  todir="${instrumented.dir}">
			<!--
				The following line causes instrument to ignore any
				source line containing a reference to log4j, for the
				purposes of coverage reporting.
			-->
			<ignore regex="org.apache.log4j.*" />

			<fileset dir="${classes.dir}">
				<!--
					Instrument all the application classes, but
					don't instrument the test classes.
				-->
				<include name="**/*.class" />
				<exclude name="**/*Test.class" />
			</fileset>
		</cobertura-instrument>
	</target>


   3.test ,这步是生成详细代码覆盖信息的步骤,并生成JUnit的测试结果。这里需要用instrument后的*.class替代原来的*.class,当instrument后的*.class被执行时,它们会纪录被调用的信息,并写入之前生成的信息文件cobertura.ser。
<target name="test" depends="init,compile">
		<junit fork="yes" dir="${basedir}" failureProperty="test.failed">
			<!--
				Note the classpath order: instrumented classes are before the
				original (uninstrumented) classes.  This is important.
			-->
			<classpath location="${instrumented.dir}" />
			<classpath location="${classes.dir}" />

			<!--
				The instrumented classes reference classes used by the
				Cobertura runtime, so Cobertura and its dependencies
				must be on your classpath.
			-->
			<classpath refid="cobertura.classpath" />

			<formatter type="xml" />
			<test name="${testcase}" todir="${reports.xml.dir}" if="testcase" />
			<batchtest todir="${reports.xml.dir}" unless="testcase">
				<fileset dir="${src.dir}">
					<include name="**/*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>


4.生成代码覆盖率报告。
<target name="coverage-check">
		<cobertura-check branchrate="34" totallinerate="100" />
	</target>

	<target name="coverage-report">
		<!--
			Generate an XML file containing the coverage data using
			the "srcdir" attribute.
		-->
		<cobertura-report srcdir="${src.dir}" destdir="${coverage.xml.dir}" format="xml" />
	</target>

	<target name="alternate-coverage-report">
		<!--
			Generate a series of HTML files containing the coverage
			data in a user-readable form using nested source filesets.
		-->
		<cobertura-report destdir="${coverage.html.dir}">
			<fileset dir="${src.dir}">
				<include name="**/*.java"/>
			</fileset>
		</cobertura-report>
	</target>



经过分析,这些步骤中只有第三步test部分执行有问题,因为没有websphere的环境,所以我决定将第三步分离,通过项目自带的JUnit框架来调用测试类。首先我执行instrument步骤,然后启动websphere服务器。在这里,正式服务器和RAD自带的websphere有所区别。正式的服务器需要用instrument后的*.class替换原来的,打包后重新发布。测试服务器上我采用先启动,然后替换发布后的*.class。然后我通过测试框架在jsp上执行测试类,此时,所有的信息并没有写入到相应的cobertura.ser文件中,只有当server停止时,系统才会将信息写入文件。因为在测试框架执行instrument后的class时,我们无法指定信息文件的位置,所以会在C:\RAD7\SDP70\runtimes\base_v61\profiles\serverName 文件夹下生成新的cobertura.ser文件,serverName为配置的server名称。然后再利用cobertura自带的merge功能将这两个cobertura.ser文件合并.

5.merge
	<target name="merge" description="merge files">
		<cobertura-merge>
		    <fileset dir="${basedir}">
		        <include name="**/cobertura1.ser"/>
		    	<include name="**/cobertura22.ser"/>
		    </fileset>
		</cobertura-merge>
	</target>	

最后,我们再通过ant生成相应的代码覆盖率的报告.这样,我们就完成了cobertura和中间件的结合.
PS:各种中间件生成cobertura.ser的位置有所不同.但都可以通过这种方式使用cobertura.

猜你喜欢

转载自huangtut.iteye.com/blog/301239