jacoco而开合并exec,生成报告API方法改造

官方jacoco里的运行方法只提供了java -jar的方式去生成报告,合成exec,本次改造以能生成差异代码的jacoco二开版本为基础,开放了API的方式进行调用,其中需要用到jacoco二开项目里编译出来的三个jar:

jacococli.jar
org.jacoco.core-0.8.7-SNAPSHOT.jar
org.jacoco.report-0.8.7-SNAPSHOT.jar

在idea里project structure引入上述三个包,也可以通过mvn本地安装的方式安装这三个包,然后在pom里引入本地依赖,通过采取maven引入的方式便于后续的打包,这样就可以把本地依赖包一起打到包里,注意这里需要开启mvn配置里的本地仓库:将下面语句填入maven setting文件里

  <localRepository>E:\repository</localRepository>

再在idea中的terminal执行如下命令进行本地安装jar:

mvn install:install-file -Dfile=lib/org.jacoco.report-0.8.7-SNAPSHOT.jar -DgroupId=local.jacoco -DartifactId=jacoco-report -Dversion=3.4.10 -Dpackaging=jar -Dmaven.repo.local=E:\repository

Dfile指的是jar的路径,DgroupId,DartifactId,Dversion这三个变量用来后续的dependency的引入,Dmaven.repo.local指定了安装的repository地址,不指定的话就会默认安装到C盘中

<dependency>
            <groupId>local.jacoco</groupId>
            <artifactId>jacoco-report</artifactId>
            <version>3.4.10</version>
        </dependency>

        <dependency>
            <groupId>local.jacoco</groupId>
            <artifactId>jacoco-core</artifactId>
            <version>3.4.10</version>
        </dependency>

        <dependency>
            <groupId>local.jacoco</groupId>
            <artifactId>diff-jacococli</artifactId>
            <version>3.4.10</version>
        </dependency>

准备工作已就绪,下面直接来看代码:

package com.hello.hellowold;

import org.jacoco.core.analysis.Analyzer;
import org.jacoco.core.analysis.CoverageBuilder;
import org.jacoco.core.analysis.IBundleCoverage;
import org.jacoco.core.data.ExecutionData;
import org.jacoco.core.data.ExecutionDataStore;
import org.jacoco.core.internal.diff.JsonReadUtil;
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;

import java.io.FileOutputStream;
import java.io.IOException;
import java.io.File;
import java.util.ArrayList;
import java.util.List;

/**
 * @author Cheertan
 * @date 2022-08-24
 */
public class JacocoUtils {

	public static void main(String[] args) throws IOException {

//        List<String> files = new ArrayList<>();
//        String targetMergeFile = "F:\\jacoco\\service\\merge.exec";
//        files.add("F:\\jacoco\\service\\jacoco_tcp_02.exec");
//        files.add("F:\\jacoco\\service\\jacoco_tcp_03.exec");
//        mergeExec(files, targetMergeFile);
//		String differFiles = "F:\\jacoco\\service\\differ.json";
//		String classesDirectory = "F:\\workspace\\hellowold\\target\\classes";
//		String sourceDirectory = "F:\\workspace\\hellowold\\src\\main\\java";
//		String executionDataFile = "F:\\jacoco\\service\\merge.exec";
//		String reportDirectory = "F:\\jacoco\\service\\report-merge";
//
//		generateReport(classesDirectory, sourceDirectory, executionDataFile, reportDirectory);
//		generateReport(classesDirectory, sourceDirectory, executionDataFile, reportDirectory, differFiles);
	}

	public static ExecutionDataStore load(File file) throws IOException {
		ExecFileLoader loader = new ExecFileLoader();
		loader.load(file);
		return loader.getExecutionDataStore();
	}

	public static void generateReport(String classesDirectory,
			String sourceDirectory, String executionDataFile, String reportDirectory,
			String differFile) throws IOException {
		File classesDire = new File(classesDirectory);
		File soureDire = new File(sourceDirectory);
		File executionFile = new File(executionDataFile);
		File reportDire = new File(reportDirectory);
		ExecFileLoader execFileLoader = loadExecutionData(executionFile);
		IBundleCoverage bundleCoverage;
		// 对比exec和class类,生成覆盖数据
		if (differFile != null) {
			bundleCoverage = analyzeStructure(execFileLoader, classesDire,
					differFile);
		} else {
			bundleCoverage = analyzeStructure(execFileLoader, classesDire);
		}
		// 生成报告
		createReport(bundleCoverage, execFileLoader, reportDire,
				soureDire);

	}

	public static void generateReport(String classesDirectory, String sourceDirectory, String executionDataFile, String reportDirectory)
			throws IOException {
		generateReport(classesDirectory, sourceDirectory, executionDataFile,
				reportDirectory, null);
	}

	public static void mergeExec(List<String> execFiles, String destFile)
			throws IOException {
		final ExecFileLoader loader = new ExecFileLoader();
		List<File> files = new ArrayList<>();
		for (String ef : execFiles) {
		    files.add(new File(ef));
        }

		for (final File file : files) {
			// 开始加载exec文件,遍历多个文件加载
			loader.load(file);
		}
		loader.save(new File(destFile), true);
	}

	/**
	 * 第一步解析exec文件
	 *
	 * @throws IOException
	 */
	public static ExecFileLoader loadExecutionData(File executionDataFile)
			throws IOException {
		// 解析exec
		ExecFileLoader execFileLoader = new ExecFileLoader();
		execFileLoader.load(executionDataFile);
		return execFileLoader;
	}

	public static IBundleCoverage analyzeStructure(
			ExecFileLoader execFileLoader, File classesDirectory)
			throws IOException {
		return analyzeStructure(execFileLoader, classesDirectory, null);
	}

	public static IBundleCoverage analyzeStructure(
			ExecFileLoader execFileLoader, File classesDirectory,
			String diffCodeFiles) throws IOException {

		CoverageBuilder builder;
		// 如果有增量参数将其设置进去
		if (null != diffCodeFiles) {
			builder = new CoverageBuilder(
					JsonReadUtil.readJsonToString(diffCodeFiles));

		} else {
			builder = new CoverageBuilder();
		}
		final Analyzer analyzer = new Analyzer(
				execFileLoader.getExecutionDataStore(), builder);

		analyzer.analyzeAll(classesDirectory);

		return builder.getBundle("报告率");
	}

	public static void createReport(final IBundleCoverage bundleCoverage,
			ExecFileLoader execFileLoader, File reportDirectory,
			File sourceDirectory) throws IOException {

		// Create a concrete report visitor based on some supplied
		// configuration. In this case we use the defaults
		final HTMLFormatter htmlFormatter = new HTMLFormatter();
		System.out.println("***");
		final IReportVisitor visitor = htmlFormatter
				.createVisitor(new FileMultiReportOutput(reportDirectory));

		// Initialize the report with all of the execution and session
		// information. At this point the report doesn't know about the
		// structure of the report being created
		visitor.visitInfo(execFileLoader.getSessionInfoStore().getInfos(),
				execFileLoader.getExecutionDataStore().getContents());

		// Populate the report structure with the bundle coverage information.
		// Call visitGroup if you need groups in your report.
		visitor.visitBundle(bundleCoverage,
				new DirectorySourceFileLocator(sourceDirectory, "utf-8", 4));

		visitor.visitEnd();

	}

}


  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值