Jacoco动态监测Web项目的覆盖率

Jacoco动态监测Web项目的覆盖率

我自己曾经尝试用python的urllib自己dump数据,结果tomcat的后台报错。

java.io.IOException: Invalid execution data file.
        at org.jacoco.agent.rt.internal_932a715.core.data.ExecutionDataReader.read(ExecutionDataReader.java:84)
        at org.jacoco.agent.rt.internal_932a715.output.TcpConnection.run(TcpConnection.java:59)
        at org.jacoco.agent.rt.internal_932a715.output.TcpServerOutput$1.run(TcpServerOutput.java:63)
        at java.lang.Thread.run(Thread.java:619)

好奇为啥不行。翻阅Jacoco官网上的文档,找到了它的一个demo,修改参数连接到我的tomcat下dump数据,好使。

具体的配置和代码链接贴到这里,希望大家有用。希望后面有时间能扒拉一下源代码看看,本地化成自己的。

配置

下载jacoco的jar包,放到某个地方,然后在catalina.sh中配置如下:

JAVA_OPTS="-server -Xms2000m -Xmx2000m -Xmn800m -XX:PermSize=64m 
    -XX:MaxPermSize=256m -XX:SurvivorRatio=4  -XX:+UseConcMarkSweepGC 
    -XX:MaxTenuringThreshold=15 -Dfile.encoding=utf8 -Duser.language=zh 
    -javaagent:/home/auser/myproject/apache-tomcat-6.0.37/lib/
    jacocoagent.jar=includes=com.xxx.*,output=tcpserver,port=8494,
    address=10.10.10.10"

当然,针对jaococ,真正有用的是-javaagent=yourpath/jacocoagent.jar=[opt]=[val],[opt]=[val]这段:

    -javaagent:/home/iteqa/cms/apache-tomcat-6.0.37/lib/
        jacocoagent.jar=includes=com.baidu.*,output=tcpserver,port=8494,
        address=10.10.10.10"

dump数据

http://www.eclemma.org/jacoco/trunk/doc/examples/java/ExecutionDataClient.java

测试ok,能够dump出数据

生成报告

http://www.eclemma.org/jacoco/trunk/doc/examples/java/ReportGenerator.java

测试报错,can't find class loader ....

找个下班时间继续研究研究

maven依赖

该程序使用maven管理时的依赖

        org.jacoco
        org.jacoco.core
        0.7.1.201405082137
    

    
        org.jacoco
        org.jacoco.report
        0.7.1.201405082137
    

ExecutionDataClient

用于生成xxx.exec数据的程序
public class ExecutionDataClient {
    private static final String DESTFILE = "jacoco-client.exec";

    private static final String ADDRESS = "10.xx.xx.xx";

    private static final int PORT = 8494;

    /**
     * Starts the execution data request.
     * 
     * @param args
     * @throws IOException
     */
    public static void main(final String[] args) 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();
    }

    private ExecutionDataClient() {
    }
}

ReportGenerator

用于生成报告的程序
public class ReportGenerator {

    private final String title;

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

    private ExecFileLoader execFileLoader;

    /**
     * Create a new generator based for the given project.
     * 
     * @param projectDirectory
     */
    public ReportGenerator(final File projectDirectory) {
        this.title = projectDirectory.getName();
        this.executionDataFile = new File(projectDirectory, "jacoco.exec");
        this.classesDirectory = new File(projectDirectory, "bin");
        this.sourceDirectory = new File(projectDirectory, "src");
        this.reportDirectory = new File(projectDirectory, "coveragereport");
    }

    /**
     * Create the report.
     * 
     * @throws IOException
     */
    public void create() 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(final IBundleCoverage bundleCoverage)
            throws IOException {

        // Create a concrete report visitor based on some supplied
        // configuration. In this case we use the defaults
        final HTMLFormatter htmlFormatter = new HTMLFormatter();
        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));

        // 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 {
        final CoverageBuilder coverageBuilder = new CoverageBuilder();
        final Analyzer analyzer = new Analyzer(
                execFileLoader.getExecutionDataStore(), coverageBuilder);

        analyzer.analyzeAll(classesDirectory);

        return coverageBuilder.getBundle(title);
    }

    /**
     * Starts the report generation process
     * 
     * @param args
     *            Arguments to the application. This will be the location of the
     *            eclipse projects that will be used to generate reports for
     * @throws IOException
     */
    public static void main(final String[] args) throws IOException {
        for (int i = 0; i < args.length; i++) {
            final ReportGenerator generator = new ReportGenerator(new File(
                    args[i]));
            generator.create();
        }
    }

}

你可能感兴趣的:(web,测试,Java)