首页 > 代码库 > jacoco统计server端功能测试覆盖率

jacoco统计server端功能测试覆盖率

jacoco可以统计,功能测试时,server代码调用的覆盖情况。这里对服务器端的java代码进行统计。
 
操作步骤如下:
 
第一步:更改server的启动脚本,使用jacocoagent.jar启动服务
 
1.下载jacocoagent.jar
http://www.jacoco.org/jacoco/index.html
 
jacocoagent.jar在下载的zip的./lib/目录下,使用方法-javaagent:[yourpath/]jacocoagent.jar=[option1]=[value1],[option2]=[value2]
 
2.修改启动server的参数,使用jacocoagent.jar记录服务的操作数据
启动项增加下面内容:
-javaagent:/opt/soft/jacoco/lib/jacocoagent.jar=destfile=/home/work/jacoco/${SERVICE_NAME}/${SERVICE_NAME}jacoco.exec,append=true,classdumpdir=/home/work/jacoco/${SERVICE_NAME/class/,includes=com.*,excludes=*.scf.*:*.entity.*:*.entitys.*,output=file"
 
说明:
1.javaagent:后面跟jacocoagent.jar的地址
2.destfile为输出的exec的保存地址,exec文件是用来分析覆盖率的
3.classdumpdir:agent调用到的所有class文件存储的位置
 
更多jacocoagent.jar的参数详见官网:http://www.eclemma.org/jacoco/trunk/doc/agent.html
 
 
第二步:生成覆盖率报告
1.下载jacoco的包(这里是使用maven进行下载)
<dependencies>
<!-- https://mvnrepository.com/artifact/org.jacoco/jacoco-maven-plugin -->
<dependency>
    <groupId>org.jacoco</groupId>
    <artifactId>jacoco-maven-plugin</artifactId>
    <version>0.7.9</version>
</dependency>
</dependencies>
 
 
2.从服务器上拿生成的exec文件放到要生成报告的机器上
exec地址为启动脚本中destfile指定的文件
理论上不用杀server进程就可以直接copy到最新的exec文件,但是如果遇到报告结果是空的情况,可以考虑先kill server进程,再拷贝exec文件
 
3.创建工程,新建java类ReportGenerator,用来生成报告

import java.io.File;
import java.io.IOException;

import org.jacoco.core.analysis.Analyzer;
import org.jacoco.core.analysis.CoverageBuilder;
import org.jacoco.core.analysis.IBundleCoverage;
import org.jacoco.core.tools.ExecFileLoader;
import org.jacoco.report.DirectorySourceFileLocator;
import org.jacoco.report.FileMultiReportOutput;
import org.jacoco.report.IReportVisitor;
import org.jacoco.report.html.HTMLFormatter;
 
public class testjacoco {

    private final String title;

    private final File executionDataFile;
    private final File classesDirectory;
    private final File sourceDirectory;
    private final File reportDirectory;

    private ExecFileLoader execFileLoader;
    public testjacoco(final File projectDirectory ) {
        this.title = projectDirectory.getName();
        this.executionDataFile = new File(projectDirectory, "scfzzpostjacoco.exec");//覆盖率的exec文件地址
        this.classesDirectory = new File(projectDirectory, "/");//目录下必须包含源码编译过的class文件,用来统计覆盖率。所以这里用server打出的jar包地址即可
//        this.sourceDirectory =null;
        this.sourceDirectory = new File("/opt/RD_Code/server/zhuanzhuan_scf_zzpost_4-0-38_BRANCH/service/", "src/main/java");//源码的/src/main/java,只有写了源码地址覆盖率报告才能打开到代码层。使用jar只有数据结果
        this.reportDirectory = new File(projectDirectory, "coveragereport");//要保存报告的地址
    }

   
    public void create() throws IOException {
        loadExecutionData();
 
        final IBundleCoverage bundleCoverage = analyzeStructure();

        createReport(bundleCoverage);

    }

    private void createReport(final IBundleCoverage bundleCoverage)
            throws IOException {
        final HTMLFormatter htmlFormatter = new HTMLFormatter();
        final IReportVisitor visitor = htmlFormatter
                .createVisitor(new FileMultiReportOutput(reportDirectory));
 
        visitor.visitInfo(execFileLoader.getSessionInfoStore().getInfos(),
                execFileLoader.getExecutionDataStore().getContents());
        visitor.visitBundle(bundleCoverage, new DirectorySourceFileLocator(
                sourceDirectory, "utf-8", 4));
        visitor.visitEnd();

    }

    private void loadExecutionData() throws IOException {
        execFileLoader = new ExecFileLoader();
        execFileLoader.load(executionDataFile);
    }

    private IBundleCoverage analyzeStructure() throws IOException {
        final CoverageBuilder coverageBuilder = new CoverageBuilder();
        final Analyzer analyzer = new Analyzer(
                execFileLoader.getExecutionDataStore(), coverageBuilder);

        analyzer.analyzeAll(classesDirectory);

        return coverageBuilder.getBundle(title);
    }
 
    public static void main(final String[] args) throws IOException {
        testjacoco generator = new testjacoco(new File("/opt/RD_Code/server/untitled/"));//传递工程目录
            generator.create();
    }
}

 

说明:主要调用testjacoco()方法来做入口生成报告
1.this.title:报告的标题
2.this.executionDataFile:第一步生成的exec的文件
3.this.classesDirectory:源码的class文件,只要传递class所在的目录就可以(或者用编译过的jar包也可以),不传递会报错,用来统计覆盖率
4.this.sourceDirectory:源码目录,可以不赋值使用null,但这种覆盖率结果只有看到方法名级别,不能直接看到方法中具体的覆盖结果
5.new File():实际是获得第一个参数+第二个参数的地址,转为File对象
 
 
官方demo的源码:http://www.eclemma.org/jacoco/trunk/doc/examples/java/ReportGenerator.java
 
 
结果如下:
技术分享
技术分享
红色表示未覆盖,绿色表示覆盖到了,黄色表示覆盖到分支了
 
如果.this.sourceDirectory没有指定源码,是进入不了上面第二张图的
 
 
其他:jacoco还有很多其他接口,但是我不会用,如果大家有好的资料可以分享一下。
比如ExecutionDataServer这个方法应该可以远程获得服务的exec结果来分析但是我这里的结果一直是空的。有了解的可以说一下哈~
 

jacoco统计server端功能测试覆盖率