1)修改远程tomcat下的bin/catalina.sh中JAVA_OPTS的配置
----------------------------------------------------------------
# -javaagent: 的后面跟jacoco的安装路径
# includes= 选项,选择你要覆盖率的服务
# port= 选项,选择你要打开的端口
# address= 选项,tomcat服务所在机器的ip地址(如果想在跟tomcat服务同一台机器上执行ant任务的话,需要改为127.0.0.1)
----- Execute The Requested Command ------------------------------
JAVA_OPTS="-javaagent:/path/to/your/jacoco_0.8.5/lib/jacocoagent.jar=includes=com.*,output=tcpserver,port=8893,address=10.81.14.77"
2)在开发环境pom.xml中引入jacoco的jar包
<!--使用jacoco对web工程生成全部的覆盖率报告-->
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.core</artifactId>
<version>0.8.5</version>
</dependency>
<dependency>
<groupId>org.jacoco</groupId>
<artifactId>org.jacoco.report</artifactId>
<version>0.8.5</version>
</dependency>
3)调用代码实现
package com.wangfg.jacoco;
import org.jacoco.core.data.ExecutionDataWriter;
import org.jacoco.core.runtime.RemoteControlReader;
import org.jacoco.core.runtime.RemoteControlWriter;
import org.junit.Test;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;
/**
* 用于生成xxx.exec数据的程序
*/
public class ExecutionDataClient {
private static final String DESTFILE = "jacoco-client.exec";
private static final String ADDRESS = "127.0.0.1";
private static final int PORT = 8044;
/**
* Starts the execution data request.
*
* @throws IOException
*/
@Test
public void test() throws IOException {
final FileOutputStream localFile = new FileOutputStream(DESTFILE);
final ExecutionDataWriter localWriter = new ExecutionDataWriter(
localFile);
// Open a socket to the coverage agent:
final Socket socket = new Socket(InetAddress.getByName(ADDRESS), PORT);
final RemoteControlWriter writer = new RemoteControlWriter(
socket.getOutputStream());
final RemoteControlReader reader = new RemoteControlReader(
socket.getInputStream());
reader.setSessionInfoVisitor(localWriter);
reader.setExecutionDataVisitor(localWriter);
// Send a dump command and read the response:
writer.visitDumpCommand(true, false);
reader.read();
socket.close();
localFile.close();
}
}
package com.wangfg.jacoco;
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;
import org.junit.Test;
import java.io.File;
import java.io.IOException;
public class ReportGenerator {
private final String title = "jacoco-demo";
private final File executionDataFile = new File("C:\Users\Administrator\Downloads\jacoco\jacoco-client.exec");
private final File classesDirectory = new File("C:\Users\Administrator\Downloads\jacoco\target\classes\com\wangfg\jacoco\controller");
private final File sourceDirectory= new File("C:\Users\Administrator\Downloads\jacoco\src");
private final File reportDirectory = new File("C:\Users\Administrator\Downloads\jacoco\coveragereport");
private ExecFileLoader execFileLoader;
/**
* Create the report.
*
* @throws IOException
*/
@Test
public void test() throws IOException {
// Read the jacoco.exec file. Multiple data files could be merged
// at this point
loadExecutionData();
// Run the structure analyzer on a single class folder to build up
// the coverage model. The process would be similar if your classes
// were in a jar file. Typically you would create a bundle for each
// class folder and each jar you want in your report. If you have
// more than one bundle you will need to add a grouping node to your
// report
final IBundleCoverage bundleCoverage = analyzeStructure();
createReport(bundleCoverage);
}
private void createReport(IBundleCoverage bundleCoverage)
throws IOException {
// Create a concrete report visitor based on some supplied
// configuration. In this case we use the defaults
HTMLFormatter htmlFormatter = new HTMLFormatter();
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));
// Signal end of structure information to allow report to write all
// information out
visitor.visitEnd();
}
private void loadExecutionData() throws IOException {
execFileLoader = new ExecFileLoader();
execFileLoader.load(executionDataFile);
}
private IBundleCoverage analyzeStructure() throws IOException {
CoverageBuilder coverageBuilder = new CoverageBuilder();
Analyzer analyzer = new Analyzer(
execFileLoader.getExecutionDataStore(), coverageBuilder);
analyzer.analyzeAll(classesDirectory);
return coverageBuilder.getBundle(title);
}
}
4)分别执行以上代码即可得到远程代码的覆盖率。