PAYATHON 2026

Apache Ant 中 JUnit 测试通过,为什么没有生成 JaCoCo 的 jacoco.exec?

数据小陈

结论

配置中已经设置了 fork="true" 和 forkmode="once",不能将问题归因于没有启用独立 JVM。现有日志能确认 4 个测试通过,但无法确定覆盖率文件为什么没有出现。

建议先核对输出路径。配置中写的是 ${jacoco.dir}/jacoco.exec,问题中查找的却是 target/jacoco.exec。需要先确认 ${jacoco.dir} 的实际值,才能判断这两个位置是否一致。

先确认文件应该写到哪里

例如,如果 ${jacoco.dir} 的值为 target/jacoco,配置对应的文件就是 target/jacoco/jacoco.exec。原始材料没有给出该属性的定义,路径不一致是否是原因还需核实。

在 jacoco:coverage 前增加以下代码,将目标文件转换为绝对路径并打印出来:

<property name="jacoco.exec.absolute"
          location="${jacoco.dir}/jacoco.exec"/>
<echo message="JaCoCo execution data: ${jacoco.exec.absolute}"/>

然后让 destfile 使用这个属性,再按日志中的完整路径检查文件。

在测试结束后检查文件是否存在

保留原来的编译步骤,将覆盖率执行部分调整为下面的形式。示例沿用现有的 classpath 和测试匹配规则:

<jacoco:coverage output="file"
                 destfile="${jacoco.exec.absolute}"
                 dumponexit="true">
    <junit fork="true"
           forkmode="once"
           printsummary="on"
           haltonfailure="true"
           haltonerror="true"
           failureproperty="tests.failed"
           errorproperty="tests.failed">
        <classpath>
            <path refid="test.classpath"/>
            <pathelement location="${test.classes.dir}"/>
            <pathelement location="${classes.dir}"/>
        </classpath>
        <batchtest fork="true" todir="${junit.report.dir}">
            <formatter type="plain"/>
            <fileset dir="${test.classes.dir}"
                     includes="*Tests.class"/>
        </batchtest>
    </junit>
</jacoco:coverage>

<fail message="JaCoCo execution data not found: ${jacoco.exec.absolute}">
    <condition>
        <not>
            <available file="${jacoco.exec.absolute}" type="file"/>
        </not>
    </condition>
</fail>

output="file" 配合 dumponexit="true" 时,执行数据会在测试 JVM 退出时写入目标文件。dumponexit 默认为 true,这里显式写出是为了方便核对配置;仅添加这一项不能保证解决故障。JaCoCo Java Agent 文档

这段检查只能确认文件是否存在,无法确认它是否由本次运行生成,也无法确认覆盖率内容是否正确。排查时还应查看文件修改时间,避免把旧文件当作本次结果。

绝对路径下仍没有文件时,检查启动和写入过程

使用详细日志重新执行同一个 target:

ant -verbose test

重点检查以下内容:

  • 测试 JVM 的启动参数中是否包含 JaCoCo 对应的 -javaagent:,其中的 destfile 是否指向预期路径。
  • 测试进程输出中是否出现文件访问、Agent 初始化或类插桩相关错误。
  • 测试 JVM 使用的账户是否能够写入该目录。日志中的 mkdir 成功只能说明 Ant 创建了目录,不能单独证明后续文件写入成功。
  • 是否存在强制终止 JVM 的测试代码、外部进程管理操作,或测试后删除输出文件的构建步骤。

如果详细日志没有展示完整启动参数,可以使用 ant -debug test。原始日志中的 Enhancing junit with coverage 表示包装任务执行到了增强步骤,不能仅凭这一行确认文件已经成功写入。

不要用生成报告来修复执行数据缺失

jacoco.exec 是覆盖率执行数据文件。jacoco:report 读取执行数据和 class 文件,生成 HTML、XML 或 CSV 报告;应先解决执行数据文件缺失的问题。JaCoCo Ant Tasks 文档

如果按绝对路径仍找不到文件,继续定位需要完整的 ${jacoco.dir} 定义、JaCoCo taskdef、Ant/JDK/JaCoCo 版本,以及测试 JVM 的启动和退出日志。当前材料不足以认定某个版本存在缺陷,也无法保证某项配置调整能最终修复问题。

备注:内容仅供参考。