使用 Cobertura 在 Jenkins 中显示源代码的代码覆盖率(运行 来自其他机器的结果)

Show code coverage with a source code in Jenkins wiht Cobertura (run result from other machine)

背景

我有一个目录结构复杂的大型 C++ 应用程序。结构太深以至于代码存储库不能存储在 Jenkins 工作区中,而是一些根目录,否则由于路径长度限制被破坏而构建失败。

现在由于应用程序是在不同的环境中测试的,所以测试应用程序是 运行 在不同的机器上。应用程序和所有资源都被压缩并复制到测试机器,其中使用 OpenCppCoverage 进行测试 运行,结果生成了 Cobertura xml。

现在,由于需要源代码来显示 covarage 结果 xml 被复制回构建机器,然后提供给 Jenkins Cobertura 插件。

问题

覆盖率报告仅显示模块或源代码的百分比结果。代码内容不显示,但显示此错误消息:

Source

Source code is unavailable. Some possible reasons are:

  • This is not the most recent build (to save on disk space, this plugin only keeps the most recent build’s source code).
  • Cobertura found the source code but did not provide enough information to locate the source code.
  • Cobertura could not find the source code, so this plugin has no hope of finding it.
  • You do not have sufficient permissions to view this file.

现在我发现 this SO answear 很有希望:

The output xml file has to be in the same folder as where coverage is run, so:

coverage xml -o coverage.xml

The reference to the source folder is put into coverage.xml and if the output file is put into another folder, the reference to the source folder will be incorrect.

问题在于:

[Cobertura] Publishing Cobertura coverage report...

FATAL: Unable to find coverage results

java.io.IOException: Expecting Ant GLOB pattern, but saw 'C:/build_coverage/Products/MyMagicProduct/Src/test/*Coverage.xml'. See http://ant.apache.org/manual/Types/fileset.html for syntax

这是 xml 结果的一部分(修改前):

<?xml version="1.0" encoding="utf-8"?>
<coverage line-rate="0.63669186741173223" branch-rate="0" complexity="0" branches-covered="0" branches-valid="0" timestamp="0" lines-covered="122029" lines-valid="191661" version="0">
  <sources>
    <source>c:</source>
    <source>C:</source>
  </sources>
  <packages>
    <package name="C:\jenkins\workspace\MMP_coverage\MyMagicProduct\src\x64\Debug\MMPServer.exe" line-rate="0.63040511358728513" branch-rate="0" complexity="0">
      <classes>
        <class name="AuditHandler.cpp" filename="build_coverage\Products\MyMagicProduct\Src\Common\AuditHandler.cpp" line-rate="0.92682926829268297" branch-rate="0" complexity="0">
          <methods/>
          <lines>
            <line number="18" hits="1"/>
            <line number="19" hits="1"/>
            <line number="23" hits="1"/>
            <line number="25" hits="1"/>
            <line number="27" hits="1"/>
            ....
          </lines>
        </class>
   ....

最大的问题是我不确定 xml 的位置是否确实是一个问题,因为插件不会报告尝试 fetch/find 相应源代码时遇到的问题的详细信息。来自 Cobertura 的第二个项目符号可以解释问题完全令人困惑:

Cobertura found the source code but did not provide enough information to locate the source code.

我还尝试了什么

  1. 我已经确保任何人都可以阅读源代码(以避免访问问题)
  2. 我修改了 xml,因此 filename 包含相对于以下内容的路径:jenkins 工作区,xml 包含覆盖率报告的文件所在的路径
  3. 将我的源代码复制到不同的位置,甚至包含 "cobertura" 目录,因为 something like this I've found in plugin source code
  4. 我已尝试通过检查源代码来了解问题。
  5. 我发现了一些(有点旧)github project 这可能是一个提示如何修复它 - 目前我正在尝试了解它到底做了什么(我不想将这个项目导入到我的构建结构)。

到目前为止没有运气。

更新:

突然间(我不确定我做了什么)它对我的帐户有效。问题是它只对我有效,所有其他用户都有同样的问题。这清楚地表明该问题必须是证券。

当我不得不为一个非常大的 C++ 客户端开发一个 CI 管道时,我遇到了一个非常相似的问题。如果我避免 Cobertura Plugin and instead used the HTML Publisher Plugin,我会得到最好的结果。我遇到的主要问题也是找到源文件。

  1. OpenCppCoverage 结果转换为 HTML

这一步很简单。您必须将参数 --export_type=html:<outputPath>(参见 Commandline-reference)添加到 OpenCppCoverage 调用。

mkdir CodeCoverage
OpenCppCoverage.exe --export_type=html:CodeCoverage <GoogleTest.exe>

上面的命令应该在目录 <jenkins_workspace>/CodeCoverage/index.html

中产生一个 html 文件
  1. 发布 OpenCppCoverage 结果

为此,我们使用上面提到的 HTML Publisher PluginreportDir 是在第一步中创建的目录,其中包含我们的 html 文件。它的路径是相对于 Jenkins 工作区的。

    publishHTML target: [
      allowMissing: false,
      alwaysLinkToLastBuild: true,
      keepAll: true,
      reportDir: 'CodeCoverage',
      reportFiles: 'index.html',
      reportName: 'Code Coverage'
      ]

为了确保每个人都可以在本地下载和检查结果,我们将 OpenCppCoverage:

的结果归档
   archiveArtifacts artifacts: 'CodeCoverage/*.*'

您现在可以在 Code Coverage 下管道的侧边栏中看到结果,结果如下所示:

这是对我有用的解决方案。

我希望这至少能有所帮助。我只能建议避免 Cobertura Plugin。我浪费了很多时间尝试修复它并识别我的来源...

好的,我找到了使用此插件时出现问题的原因。

  1. xml 来自 openCppCoverage 是正确的。此处无需更改即可使其正常工作(只要源代码位于 pdb 文件指向的位置)。 Jenkins 工作区之外的来源不是这里的问题。当我将可执行文件从构建机器复制到测试机器时,然后 运行 使用 openCppCoverage 进行测试并将结果复制回构建机器就可以了。

  2. 在作业配置中,任何应该查看代码覆盖率的用户都必须能够访问安全部分中的 Job/workspace。就我而言,我已经为所有登录用户启用了此功能。 这涵盖了错误消息的最后一个要点。

  3. 最重要的是:构建必须成功。我的意思是从头到尾。如果包含调用 cobertura 插件的步骤成功,则不计量。如果任何步骤(即使在未来的步骤中)失败,那么 cobertura 将不会显示此覆盖范围的代码 运行。在我的例子中,由于其中一项测试超时,构建工作失败了。这是由 openCppCoverage 开销引起的,它使测试速度减慢 3。我的脚本正在检测超时并终止其中一个测试。

我偶然发现构建不成功是个问题。在实验过程中,我注意到 cobertura 显示源代码的两种情况:

  • 我已经重新运行 工作并删除了所有步骤,只有一个负责发布花腔结果
  • 我运行整个工作都是这样运行一个测试用例通过了

如果构建不成功则不播种覆盖是合理的(如果测试失败则很可能采用了错误的代码分支),但 UI 应该以不同的方式表明这一点。

结论

这是一个很好的例子,说明向用户报告错误并提供准确的错误信息和原因的重要性。我至少浪费了整个虚弱的时间来弄清楚到底出了什么问题,错误消息的哪个要点实际上是我的情况。事实上,来自插件的错误消息并没有涵盖所有不显示代码的原因。

我会提交报告,插件应该更好地解释问题所在。