最近在做代码覆盖的工作,我们采用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 block
System.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 block
e.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
#需要收集的远程服务ip
Emma.RemotePcIp=10.132.97.58
#em文件存放位置
Emma.CoverageEmDirectoryFilename=F:\\TestFile\\creditcore_coverage.em
#report产生类型,可以支持xml,txt,html
Emma.ReportType=html
#定时执行时间cron表达式
Emma.TaskTime=0 53 19 ? * *