如何正确 运行 Eclemma 覆盖 Java

How to properly run Eclemma coverage with Java

我们使用非java 测试。他们每个人都执行我们写在 Java 中的工具。 我正在尝试使用 Eclemma 来创建测试的覆盖率报告。 让我们从一个测试开始。我们用 build.xml 编译代码。我想以某种方式为每个测试创建一个覆盖率报告,然后将它们合并到一个主报告中。 我发现我可以使用 Jacoco has CMD interface 来合并这些报告。但是我不明白如何 运行 带有覆盖包的工具?

  1. 我应该使用哪个覆盖包?是 Eclemma 还是 Jacoco?
  2. 如何 运行 工具与覆盖包?我应该将它添加到 build.xml 文件中吗?我应该将它添加到命令行吗?

我对 Java 中覆盖的整个概念有点困惑。在 Python 和 Perl 等动态语言中,我只是使用覆盖率模块执行代码,它会创建覆盖率报告。

我们用来执行out工具的命令:

gandu -vm /usr/pkgs/java/1.6.0.25-64/bin/java -configuration /.ganduData -data /.ganduData -configuration /ganduInternalConfig --session_id 1582722179

我应该添加一些选项吗?

build.xml中的构建:

<target name="pde-build" depends="clean, init">
    <java classname="org.eclipse.equinox.launcher.Main" fork="true" failonerror="true">
        <arg value="-application" />
        <arg value="org.eclipse.ant.core.antRunner" />
        <arg value="-buildfile" />
        <arg value="${eclipseLocation}/plugins/org.eclipse.pde.build_${pdeBuildPluginVersion}/scripts/productBuild/productBuild.xml" />
        <arg value="-Dtimestamp=${timestamp}" />
        <classpath>
            <pathelement location="${eclipseLocation}/plugins/org.eclipse.equinox.launcher_${equinoxLauncherPluginVersion}.jar" />
        </classpath>
    </java>
</target>

我应该添加以下命令吗?

<arg value="-autVMArgs" />      
<arg value="-Xmx800m;-XX:MaxPermSize=600M;-javaagent:${jacoco-agent-path}=destfile=${jacoco-report},append=true"/>

更新: 多亏了这两个答案,我才设法使用 CLI 创建报告。但看起来它显示(几乎)零覆盖率。它在我看到已执行的打印行上显示红色(未覆盖)(它们被打印到标准输出)。

该项目包含很多包,但第一次尝试时,我尝试为特定包创建覆盖率报告。我运行:

gandu -vm /usr/pkgs/java/1.6.0.25-64/bin/java -configuration /.ganduData -data /.ganduData --session_id 1583967465 -vmargs -Xmx256m -Xms128m -javaagent:/jacoco_coverage/jacoco-0.8.5/lib/jacocoagent.jar

然后我运行:

/usr/pkgs/java/1.6.0.16-64/bin/java -jar /jacoco_coverage/jacoco-0.8.5/lib/jacococli.jar report jacoco.exec --classfiles /gandu_repo/com.core.gandu/bin/ --html temp_dir --sourcefiles /gandu_repo/com.core.gandu/src/

输出:

[WARN] Some classes do not match with execution data.
[WARN] For report generation the same class files must be used as at runtime.
[WARN] Execution data for class <PATH> does not match.
[INFO] Analyzing 8 classes.

我很难理解 classfilessourcefiles。我试图覆盖的文件是 Application。在 bin 中,我有一些内部文件夹 Application.class,在 src 中,我有一些内部文件夹 Application.java。我什至尝试为 classfilessourcefiles 中的那些文件添加完整路径,但仍然没有覆盖(全部为红色)。可能是什么问题呢? 工具结构: 根目录包含很多包,每个包都有文件夹 binsrc。每个 src 包含递归的文件夹和 Java 个文件。 binclass 文件具有相同的结构。

As I know, the only place to add java agent is in the configuration of the unit tests.

应将代理添加到执行被测应用程序的 JVM。您的困惑可能来自于通常单元测试与被测代码在同一 JVM 中执行的事实。

根据您的描述,不清楚 JVM 与应用程序是如何启动的。

但是考虑以下 src/Main.java 作为示例:

import java.io.BufferedReader;
import java.io.InputStreamReader;

public class Main {

  public static void main(String[] args) throws Exception {
    String input;
    try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in))) {
      input = reader.readLine();
    }
    if ("hello".equals(input)) {
      System.out.println("Hello, World!");
    }
  }

}

编译后

javac -d classes src/Main.java

此应用程序可以在 JVM 中使用 JaCoCo Java Agent taken from JaCoCo zip distribution 执行,如下所示

java -javaagent:jacoco/lib/jacocoagent.jar -cp classes Main

然后执行测试 - 例如在这种情况下手动输入 "hello".

JVM 正常终止后,您将获得 jacoco.exec 个文件。

通过将此 jacoco.exec、源文件和 class 文件传递​​给 JaCoCo Command Line Interface,您可以创建 HTML 报告:

java -jar jacoco/lib/jacococli.jar report jacoco.exec --classfiles classes --sourcefiles src --html report

Which coverage package should I use? Is it Eclemma or Jacoco?

EclEmma 是一个基于 JaCoCo 的 Eclipse IDE 插件。

如果为了测试您从 Eclipse 执行您的应用程序 IDE 那么您可以使用 EclEmma 通过 JaCoCo 启动它。这是在 Eclipse IDE:

中执行的相同示例

但是这不适用于Ant构建等其他场景。

How do I run the tool with the coverage package? Should I add it into the build.xml file? Should I add it to the command line?

这取决于您如何执行您的应用程序 - 如果为了测试您的应用程序是由 Ant 执行的,那么您可以使用 JaCoCo Ant Tasks 来配置代理和生成报告。作为示例,这里的 build.xml for Ant 为 src/Example.java 生成与上述命令相同的报告:

<project xmlns:jacoco="antlib:org.jacoco.ant" name="Example Ant Build with JaCoCo" default="rebuild">

  <taskdef uri="antlib:org.jacoco.ant" resource="org/jacoco/ant/antlib.xml">
    <classpath path="jacoco/lib/jacocoant.jar"/>
  </taskdef>

  <target name="clean">
    <delete dir="classes"/>
    <delete dir="report"/>
    <delete file="jacoco.exec"/>
  </target>

  <target name="compile">
    <mkdir dir="classes"/>
    <javac srcdir="src" destdir="classes" debug="true" includeantruntime="false"/>
  </target>

  <target name="run" depends="compile">
    <jacoco:agent property="jacocoAgent" />

    <java classname="Main" fork="true">
      <classpath path="classes"/>
      <jvmarg value="${jacocoAgent}"/>
    </java>
  </target>

  <target name="report" depends="run">
    <jacoco:report>
      <executiondata>
        <file file="jacoco.exec"/>
      </executiondata>
      <structure name="JaCoCo Ant Example">
        <classfiles>
          <fileset dir="classes"/>
        </classfiles>
        <sourcefiles encoding="UTF-8">
          <fileset dir="src"/>
        </sourcefiles>
      </structure>
      <html destdir="report"/>
    </jacoco:report>
  </target>

  <target name="rebuild" depends="clean,report"/>

</project>

如果应用程序是由一些自定义的自制工具执行的,那么直接将代理添加到命令行可能会更好。