最近在做代码覆盖的工作,我们采用emma做为覆盖率收集的工具,但是由于需要在命令行敲打emma命令来进行instrument 和 collection,特别是要运程收集服务器上的代码覆盖率的话,不免会比较麻烦,由于公司版本发布交频繁,功能测试可能每天会执行多次版本的回归,为了能确定每个版本代码的覆盖率以及方便收集覆盖率,本人利用spring,quartz以及emma本身写了一个定时收集覆盖率的小工具,利用这个小工具可以在spring容器来管理测试任务,并且在配置文件中配置相关项目的内容,下面上主菜,代码已经上传google code,需要的朋友可以联系我。
将emma插桩命令集成到hudson中,每当hudson完成应用程序部署自动对相应应用jar包插桩产生coverage.em文件,由于需要远程收集覆盖率信息,并且需要定时收集覆盖率信息,为了方便使用emma,本人利用spring和quartz写了一个简易的定时框架用来收集远程机器上的coverage.ec并生成报告。现将代码附上:
spring applicationContext.xml文件内容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"><beans><!--要调度的对象 --><bean id="propertyConfigurer"class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"><property name="locations"><list><value>classpath:cmd.properties</value><value>classpath:cmd2.properties</value><!--要是有多个配置文件,只需在这里继续添加即可 --></list></property></bean> <!--第一个job --><bean id="job" class="com.emmatask.EmmaTask"><property name="projectDirectory"><value>${Emma.ProjectDirectory}</value></property><property name="coverageEcDirectory"><value>${Emma.CoverageEcOutPutDirectory}</value></property><property name="coverageEcDirectoryFilename"><value>${Emma.CoverageEcOutPutDirectoryFilename}</value></property><property name="reportOutputDir"><value>${Emma.CoverageReportDirectory}</value></property><property name="remoteIp"><value>${Emma.RemotePcIp}</value></property><property name="coverageEm"><value>${Emma.CoverageEmDirectoryFilename}</value></property><property name="reportType"><value>${Emma.ReportType}</value></property><property name="coverageFilename"><value>${Emma.CoverageReportDirectoryFilename}</value></property></bean><!-- 定义第一个目标bean和bean中的方法 -->
<bean id="jobtask"class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean"><property name="targetObject"><ref local="job" /></property><property name="targetMethod"><value>collectAndGeneratorCoverageReport</value></property></bean><!-- 定义第一个任务触发的时间 -->
<bean id="cron" class="org.springframework.scheduling.quartz.CronTriggerBean"><property name="jobDetail"><ref bean="jobtask" /></property><property name="cronExpression"><value>${Emma.TaskTime}</value></property></bean><!-- 总管理 -->
<bean id="startQuertz" lazy-init="false" autowire="no"class="org.springframework.scheduling.quartz.SchedulerFactoryBean"><property name="triggers"><list><ref local="cron" /><ref local="cron2" /></list></property></bean></beans>
job代码如:
//此方法用于收集覆盖率信息
public void collectTheCoverageInfo() throws IOException { logger.info("start collecting the coverage info!");SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");String dirName = dateFormat.format(new Date()).toString();File file = new File(coverageEcDirectory + "\\" + dirName);file.mkdirs();path = file.getAbsolutePath();System.out.println(path);String cmd = String.format("java emma ctl -connect %s:47653 -command coverage.get,%s\\%s",remoteIp, path, coverageEcDirectoryFilename);execute(cmd);} //此方法用于产生测试报告public void generatorReport() { logger.info("start generator coverage report!");String cmd = String.format("java emma report -r %s -in %s,%s -Dreport.html.out.file=%s\\%s",reportType, coverageEm, path + "\\"+ coverageEcDirectoryFilename, path,coverageFilename);execute(cmd);} //此方法先执行覆盖率收集然后产生报告public void collectAndGeneratorCoverageReport() { try { collectTheCoverageInfo();} catch (IOException e) { // TODO Auto-generated catch blockSystem.out.println(e.getMessage());}generatorReport();} //此方法为执行cmd命令private void execute(String cmd) { try { logger.info("start execute command: " + cmd);Process p = Runtime.getRuntime().exec(cmd);InputStream out = p.getInputStream();StringBuffer stringBuffer = new StringBuffer();readOutput(out, stringBuffer);logger.info("The output of command: " + stringBuffer);} catch (IOException e) { // TODO Auto-generated catch blocke.printStackTrace();}}private void readOutput(InputStream input, StringBuffer buffer) { try { int c;while ((c = input.read()) != -1)buffer.append((char) c);} catch (Exception e) { e.printStackTrace();}}commad配置文件如下所示:
#对应项目名称,该字段暂时无用
Emma.ProjectDirectory=F:\项目\保理#coverage.ec文件存放文件夹Emma.CoverageEcOutPutDirectory=F:\\TestFile#ec文件的命名Emma.CoverageEcOutPutDirectoryFilename=coverage.ec#report存放文件夹Emma.CoverageReportDirectory=F:\\TestFile#report文件名Emma.CoverageReportDirectoryFilename=coverage#需要收集的远程服务ipEmma.RemotePcIp=10.132.97.58#em文件存放位置Emma.CoverageEmDirectoryFilename=F:\\TestFile\\creditcore_coverage.em#report产生类型,可以支持xml,txt,htmlEmma.ReportType=html#定时执行时间cron表达式Emma.TaskTime=0 53 19 ? * *