有人有 XSL 将 Boost.Test XML 日志转换为可呈现的格式吗?

发布于 2024-09-04 06:57:00 字数 475 浏览 3 评论 0原文

我有一些通过 cruisecontrol.net 运行的 C++ 项目。作为构建过程的一部分,我们编译并运行 Boost.Test 单元测试套件。我将它们配置为转储 XML 日志文件。虽然格式与 JUnit/NUnit 类似,但并不完全相同(并且缺少一些信息),因此 Cruisecontrol.net 无法获取它们。我想知道是否有人创建(或知道)现有的 XSL 转换,它将 Boost.Test 结果转换为 JUnit/NUnit 格式,或者直接转换为可呈现的 (html) 格式。

谢谢!

I have some C++ projects running through cruisecontrol.net. As a part of the build process, we compile and run Boost.Test unit test suites. I have these configured to dump XML log files. While the format is similar to JUnit/NUnit, it's not quite the same (and lacks some information), so cruisecontrol.net is unable to pick them up. I am wondering if anyone has created (or knows of) an existing XSL transform that will convert Boost.Test results to JUnit/NUnit format, or alternatively, directly to a presentable (html) format.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

独享拥抱 2024-09-11 06:57:00

我正在努力推出我自己的 Boost.Test -> JUnit XSL。请注意,这是为了使用 Boost.Test 的 XML report 输出,而不是 log 输出。这是一项正在进行的工作 - 这是我到目前为止所做的:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                exclude-result-prefixes="msxsl">

  <xsl:output method="xml"
              indent="yes"/>

  <xsl:template match="TestResult">
    <test-results>
      <xsl:attribute name="total">
        <xsl:value-of select="sum(./TestSuite/@test_cases_passed) + sum(./TestSuite/@test_cases_failed) + sum(./TestSuite/@test_cases_skipped) + sum(./TestSuite/@test_cases_aborted)"/>
      </xsl:attribute>
      <xsl:attribute name="failures">
        <xsl:value-of select="sum(./TestSuite/@test_cases_failed) + sum(./TestSuite/@test_cases_aborted)"/>
      </xsl:attribute>
      <xsl:attribute name="skipped">
        <xsl:value-of select="sum(./TestSuite/@test_cases_skipped)"/>
      </xsl:attribute>
      <xsl:attribute name="not-run">
        <xsl:value-of select="sum(./TestSuite/@test_cases_skipped)"/>
      </xsl:attribute>
      <xsl:call-template name="testSuite" />
    </test-results>
  </xsl:template>

  <xsl:template name="testSuite">
    <xsl:for-each select="TestSuite">
      <test-suite>
        <xsl:call-template name="testAttributes" />
        <results>
          <xsl:call-template name="testSuite" />
          <xsl:for-each select="TestCase">
            <test-case>
              <xsl:call-template name="testAttributes" />
            </test-case>
          </xsl:for-each>
        </results>
      </test-suite>
    </xsl:for-each>
  </xsl:template>

  <xsl:template name="testAttributes">
    <xsl:attribute name="name">
      <xsl:value-of select="@name"/>
    </xsl:attribute>
    <xsl:attribute name="success">
      <xsl:choose>
        <xsl:when test="@result = 'passed'">True</xsl:when>
        <xsl:when test="@result != 'passed'">False</xsl:when>
      </xsl:choose>
    </xsl:attribute>
    <xsl:attribute name="executed">True</xsl:attribute>
    <xsl:attribute name="time">0</xsl:attribute>
    <xsl:attribute name="asserts">
      <xsl:value-of select="@assertions_failed + @assertions_passed"/>
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

我已将其集成到我的构建过程中,并且 ccnet 很好地拾取并处理了它。它并不完美,但比我以前完全没有报告要好。我愿意接受有关如何将 Boost.Test 数据映射到 JUnit 报告的“total”、“failures”、“skipped”和“not-run”字段的建议。另外,不幸的是,错误详细数据(指示故障的性质以及发生故障的文件/行号)仅打印到日志中,而不是打印到报告中,因此我必须“合并”两者才能获取所有内容我理想中想要拥有的数据。

I'm working on rolling my own Boost.Test -> JUnit XSL. Please note that this is intended to consume the XML report output from Boost.Test - not the log output. This is a work in progress - here's what I have so far:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                exclude-result-prefixes="msxsl">

  <xsl:output method="xml"
              indent="yes"/>

  <xsl:template match="TestResult">
    <test-results>
      <xsl:attribute name="total">
        <xsl:value-of select="sum(./TestSuite/@test_cases_passed) + sum(./TestSuite/@test_cases_failed) + sum(./TestSuite/@test_cases_skipped) + sum(./TestSuite/@test_cases_aborted)"/>
      </xsl:attribute>
      <xsl:attribute name="failures">
        <xsl:value-of select="sum(./TestSuite/@test_cases_failed) + sum(./TestSuite/@test_cases_aborted)"/>
      </xsl:attribute>
      <xsl:attribute name="skipped">
        <xsl:value-of select="sum(./TestSuite/@test_cases_skipped)"/>
      </xsl:attribute>
      <xsl:attribute name="not-run">
        <xsl:value-of select="sum(./TestSuite/@test_cases_skipped)"/>
      </xsl:attribute>
      <xsl:call-template name="testSuite" />
    </test-results>
  </xsl:template>

  <xsl:template name="testSuite">
    <xsl:for-each select="TestSuite">
      <test-suite>
        <xsl:call-template name="testAttributes" />
        <results>
          <xsl:call-template name="testSuite" />
          <xsl:for-each select="TestCase">
            <test-case>
              <xsl:call-template name="testAttributes" />
            </test-case>
          </xsl:for-each>
        </results>
      </test-suite>
    </xsl:for-each>
  </xsl:template>

  <xsl:template name="testAttributes">
    <xsl:attribute name="name">
      <xsl:value-of select="@name"/>
    </xsl:attribute>
    <xsl:attribute name="success">
      <xsl:choose>
        <xsl:when test="@result = 'passed'">True</xsl:when>
        <xsl:when test="@result != 'passed'">False</xsl:when>
      </xsl:choose>
    </xsl:attribute>
    <xsl:attribute name="executed">True</xsl:attribute>
    <xsl:attribute name="time">0</xsl:attribute>
    <xsl:attribute name="asserts">
      <xsl:value-of select="@assertions_failed + @assertions_passed"/>
    </xsl:attribute>
  </xsl:template>

</xsl:stylesheet>

I have this integrated into my build process and it's getting picked up and processed by ccnet nicely. It's not perfect, but it works better than the complete lack of reporting I had before. I'm open to suggestions on how to map the Boost.Test data to the "total", "failures", "skipped", and "not-run" fields of the JUnit report. Also, unfortunately the error detail data (indicating the nature of the failure and the file/line number where the failure occurred) are only printed to the log, not to the report, so I would have to "merge" the two to get all the data I would ideally like to have.

So尛奶瓶 2024-09-11 06:57:00

感谢 Stuart Lange 的上述回答,我能够将 Boost.Test 的输出与我们的 Bamboo 构建系统集成。 Bamboo 描述了他们可以在此处摄取的格式:

http://confluence.atlassian。 com/display/BAMBOO/JUnit+parsing+in+Bamboo

因此,我使用上面 Stuart Lange 的 XSL 作为起点,最终得到以下结果:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                exclude-result-prefixes="msxsl">

  <xsl:output method="xml"
              indent="yes"/>

  <xsl:template match="TestResult">
      <xsl:call-template name="testSuite" />
  </xsl:template>

  <xsl:template name="testSuite">
    <xsl:for-each select="TestSuite">
      <testsuite>
        <xsl:attribute name="errors">
            <xsl:value-of select="@test_cases_failed + @test_cases_aborted"/>
        </xsl:attribute>

        <xsl:attribute name="tests">
            <xsl:value-of select="@test_cases_passed + @test_cases_failed + @test_cases_skipped + @test_cases_aborted"/>
        </xsl:attribute>

        <xsl:attribute name="skipped">
            <xsl:value-of select="@test_cases_skipped"/>
        </xsl:attribute>

        <xsl:attribute name="failures">
            <xsl:value-of select="@test_cases_failed"/>
        </xsl:attribute>

        <xsl:call-template name="testAttributes" />
        <!--results-->
          <xsl:call-template name="testSuite" />
          <xsl:for-each select="TestCase">
            <testcase>
              <xsl:call-template name="testAttributes" />
              <xsl:call-template name="testCaseElements" />
            </testcase>
          </xsl:for-each>
        <!--/results-->
      </testsuite>
    </xsl:for-each>
  </xsl:template>

  <xsl:template name="testAttributes">
    <xsl:attribute name="name">
      <xsl:value-of select="@name"/>
    </xsl:attribute>
    <xsl:attribute name="success">
      <xsl:choose>
        <xsl:when test="@result = 'passed'">True</xsl:when>
        <xsl:when test="@result != 'passed'">False</xsl:when>
      </xsl:choose>
    </xsl:attribute>
    <xsl:attribute name="executed">True</xsl:attribute>
    <xsl:attribute name="time">0</xsl:attribute>
    <xsl:attribute name="asserts">
      <xsl:value-of select="@assertions_failed + @assertions_passed"/>
    </xsl:attribute>
  </xsl:template>

  <xsl:template name="testCaseElements">
    <xsl:if test="@result != 'passed'">
        <failure type="No type reported" message="No message reported"/>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

当我们调用 Boost.Test 可执行文件时,我们使用以下命令行选项:

--report_format=xml
--report_level=detailed

这不是最热门的 XSL,但足以从 Bamboo 中查看套件、包含的测试以及哪些(如果有)失败。

另请注意,使用此方法您只想捕获 stderr 输出。 stdout 的内容(至少是我们使用 Boost.Test 的方式)会破坏一切。

Thanks to Stuart Lange's answer above, I was able to get Boost.Test's output to integrate with our Bamboo build system. Bamboo describes the format they can ingest here:

http://confluence.atlassian.com/display/BAMBOO/JUnit+parsing+in+Bamboo

So I used Stuart Lange's XSL above as a starting point, and ended up with this:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                exclude-result-prefixes="msxsl">

  <xsl:output method="xml"
              indent="yes"/>

  <xsl:template match="TestResult">
      <xsl:call-template name="testSuite" />
  </xsl:template>

  <xsl:template name="testSuite">
    <xsl:for-each select="TestSuite">
      <testsuite>
        <xsl:attribute name="errors">
            <xsl:value-of select="@test_cases_failed + @test_cases_aborted"/>
        </xsl:attribute>

        <xsl:attribute name="tests">
            <xsl:value-of select="@test_cases_passed + @test_cases_failed + @test_cases_skipped + @test_cases_aborted"/>
        </xsl:attribute>

        <xsl:attribute name="skipped">
            <xsl:value-of select="@test_cases_skipped"/>
        </xsl:attribute>

        <xsl:attribute name="failures">
            <xsl:value-of select="@test_cases_failed"/>
        </xsl:attribute>

        <xsl:call-template name="testAttributes" />
        <!--results-->
          <xsl:call-template name="testSuite" />
          <xsl:for-each select="TestCase">
            <testcase>
              <xsl:call-template name="testAttributes" />
              <xsl:call-template name="testCaseElements" />
            </testcase>
          </xsl:for-each>
        <!--/results-->
      </testsuite>
    </xsl:for-each>
  </xsl:template>

  <xsl:template name="testAttributes">
    <xsl:attribute name="name">
      <xsl:value-of select="@name"/>
    </xsl:attribute>
    <xsl:attribute name="success">
      <xsl:choose>
        <xsl:when test="@result = 'passed'">True</xsl:when>
        <xsl:when test="@result != 'passed'">False</xsl:when>
      </xsl:choose>
    </xsl:attribute>
    <xsl:attribute name="executed">True</xsl:attribute>
    <xsl:attribute name="time">0</xsl:attribute>
    <xsl:attribute name="asserts">
      <xsl:value-of select="@assertions_failed + @assertions_passed"/>
    </xsl:attribute>
  </xsl:template>

  <xsl:template name="testCaseElements">
    <xsl:if test="@result != 'passed'">
        <failure type="No type reported" message="No message reported"/>
    </xsl:if>
  </xsl:template>

</xsl:stylesheet>

We use the following command line options when we call our Boost.Test executable:

--report_format=xml
--report_level=detailed

It's not the hottest XSL to leave the presses, but it's enough to see the suites, the tests contained, and which ones (if any) failed from Bamboo.

One additional note, with this method you only want to capture the stderr output. The contents of stdout (at least the way we use Boost.Test) will break things.

孤蝉 2024-09-11 06:57:00

这个 xsl 适用于我将 Boost.Test 的 log.xml 转换为 Bamboo 可读的 JUnit xml,并包含消息!:
https://issues.jenkins-ci .org/secure/attachment/19613/boosttest-1.0-to-junit-1.0.xsl

从这里链接:

This xsl works for me for converting Boost.Test's log.xml to JUnit xml readable by Bamboo, complete with messages!:
https://issues.jenkins-ci.org/secure/attachment/19613/boosttest-1.0-to-junit-1.0.xsl

It's linked from here: https://issues.jenkins-ci.org/browse/JENKINS-7039

烛影斜 2024-09-11 06:57:00

我们使用 --report_format=xml --report_level=detailed --log_level=test_suite --log_format=xml 运行测试。您需要 stderr 和 stdout,那么我们将替换为与并将 替换为与。之后我们通过整洁的方式运行它,最后通过这个 xslt 运行它。

您还必须小心,stdout/err 中不要有任何 xml 样式的标记。像这样的东西可以破坏转换。

  <xsl:for-each select="./TestSuite">
    <xsl:variable name="name2" select="@name"/>
    <testsuite>
      <xsl:attribute name="errors">
        <xsl:value-of select="@test_cases_failed" />
      </xsl:attribute>
      <xsl:attribute name="tests">
        <xsl:value-of select="@test_cases_failed + @test_cases_passed + @test_cases_skipped" />
      </xsl:attribute>
      <xsl:attribute name="name">
        <xsl:value-of select="@name" />
      </xsl:attribute>
      <xsl:for-each select="./TestCase">
        <xsl:variable name="name3" select="@name"/>
        <testcase>
          <xsl:attribute name="name">
            <xsl:value-of select="@name" />
          </xsl:attribute>
          <xsl:for-each select="/xml/TestLog/TestSuite[@name=$name1]">
            <xsl:for-each select="./TestSuite[@name=$name2]">
              <xsl:for-each select="./TestCase[@name=$name3]">
                <xsl:for-each select="./TestingTime">
                  <xsl:attribute name="time">
                    <xsl:value-of select="./text() div 100000"/>
                  </xsl:attribute>
                </xsl:for-each>
                <xsl:for-each select="./Error">
                  <failure>
                    <xsl:attribute name="type">AssertionFailedError</xsl:attribute>
                    <xsl:attribute name="message">
                      <xsl:value-of select="@file"/>:<xsl:value-of select="@line"/>
                    </xsl:attribute>
                    <xsl:copy-of select="./text()"/>
                  </failure>
                </xsl:for-each>
                <xsl:for-each select="./Exception">
                  <failure>
                    <xsl:attribute name="type">AssertionFailedException</xsl:attribute>
                    <xsl:attribute name="message">
                      <xsl:value-of select="@file"/>:<xsl:value-of select="@line"/>
                    </xsl:attribute>
                    <xsl:copy-of select="./text()"/>
                  </failure>
                </xsl:for-each>
                <system-out>
                  <xsl:copy-of select="./text()"/>
                </system-out>
              </xsl:for-each>
            </xsl:for-each>
          </xsl:for-each>
        </testcase>
      </xsl:for-each>
    </testsuite>
  </xsl:for-each>
</testsuite>

We run our tests with --report_format=xml --report_level=detailed --log_level=test_suite --log_format=xml. You need both stderr and stdout, then we replace <TestLog> with <xml><TestLog> and replace </TestResult> with </TestResult><xml>. After that we run it though tidy and finally run that though this xslt.

You must also be careful not to have any xml-style tags in your stdout/err. Things like <foo> can break the conversion.

  <xsl:for-each select="./TestSuite">
    <xsl:variable name="name2" select="@name"/>
    <testsuite>
      <xsl:attribute name="errors">
        <xsl:value-of select="@test_cases_failed" />
      </xsl:attribute>
      <xsl:attribute name="tests">
        <xsl:value-of select="@test_cases_failed + @test_cases_passed + @test_cases_skipped" />
      </xsl:attribute>
      <xsl:attribute name="name">
        <xsl:value-of select="@name" />
      </xsl:attribute>
      <xsl:for-each select="./TestCase">
        <xsl:variable name="name3" select="@name"/>
        <testcase>
          <xsl:attribute name="name">
            <xsl:value-of select="@name" />
          </xsl:attribute>
          <xsl:for-each select="/xml/TestLog/TestSuite[@name=$name1]">
            <xsl:for-each select="./TestSuite[@name=$name2]">
              <xsl:for-each select="./TestCase[@name=$name3]">
                <xsl:for-each select="./TestingTime">
                  <xsl:attribute name="time">
                    <xsl:value-of select="./text() div 100000"/>
                  </xsl:attribute>
                </xsl:for-each>
                <xsl:for-each select="./Error">
                  <failure>
                    <xsl:attribute name="type">AssertionFailedError</xsl:attribute>
                    <xsl:attribute name="message">
                      <xsl:value-of select="@file"/>:<xsl:value-of select="@line"/>
                    </xsl:attribute>
                    <xsl:copy-of select="./text()"/>
                  </failure>
                </xsl:for-each>
                <xsl:for-each select="./Exception">
                  <failure>
                    <xsl:attribute name="type">AssertionFailedException</xsl:attribute>
                    <xsl:attribute name="message">
                      <xsl:value-of select="@file"/>:<xsl:value-of select="@line"/>
                    </xsl:attribute>
                    <xsl:copy-of select="./text()"/>
                  </failure>
                </xsl:for-each>
                <system-out>
                  <xsl:copy-of select="./text()"/>
                </system-out>
              </xsl:for-each>
            </xsl:for-each>
          </xsl:for-each>
        </testcase>
      </xsl:for-each>
    </testsuite>
  </xsl:for-each>
</testsuite>

小矜持 2024-09-11 06:57:00

有趣的是,以上内容都不适合我,也许是因为较新的 CruiseControl (2.8.4),但无论如何。 CruiseControl 忽略上述转换创建的所有“错误”和“失败”属性,并对子元素执行自己的查询。现在,这实际上显示了有多少测试成功,哪些测试失败。

最好也从 boost 测试日志文件中折叠出更具体的故障信息(但也许其他人可以从这里获取)。

关键点:为 Boost.Test 指定以下标志以拆分 stdout/stderr。这是 ant 构建脚本的快照:

<exec executable="cmd " dir="bin/x64/Release">
<arg line="/k @{file} --build_info --report_format=xml --report_level=detailed --log_level=all --log_format=xml 1> @{file}.log.xml 2> @{file}.result.xml"/>
</exec>

然后对其进行转换:

  <xslt in="@{file}.result.xml" out="@{file}.ccresult.xml" style="transform.xslt" /> 

实际的 transform.xslt:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                exclude-result-prefixes="msxsl"
>
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/TestResult/TestSuite">
    <testsuite>
      <xsl:attribute name="name">
        <xsl:value-of select="@name"/>
      </xsl:attribute>

      <xsl:for-each select="TestCase">
        <testcase>
          <xsl:attribute name="name">
            <xsl:value-of select="@name"/>
          </xsl:attribute>
          <xsl:if test="@result!='passed'">
            <failure>See log file.</failure>
          </xsl:if>
        </testcase>
      </xsl:for-each>
    </testsuite>
  </xsl:template>
</xsl:stylesheet>

Interestingly enough none of the above worked for me, maybe because of newer CruiseControl (2.8.4), but whatever. CruiseControl ignores all the 'errors' and 'failures' attributes that above transforms create, and does it's own queries on the child elements. Now this shows actually how many tests succeeded and which ones failed.

It would be nice to fold in more specific failure info from the boost test log file as well (but maybe somebody else can pick up from here).

Key point: specify following flags to Boost.Test to split out stdout/stderr. Here is a snapshot from an ant build script:

<exec executable="cmd " dir="bin/x64/Release">
<arg line="/k @{file} --build_info --report_format=xml --report_level=detailed --log_level=all --log_format=xml 1> @{file}.log.xml 2> @{file}.result.xml"/>
</exec>

Then transform it:

  <xslt in="@{file}.result.xml" out="@{file}.ccresult.xml" style="transform.xslt" /> 

The actual transform.xslt:

<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="1.0"
                xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:msxsl="urn:schemas-microsoft-com:xslt"
                exclude-result-prefixes="msxsl"
>
  <xsl:output method="xml" indent="yes"/>

  <xsl:template match="/TestResult/TestSuite">
    <testsuite>
      <xsl:attribute name="name">
        <xsl:value-of select="@name"/>
      </xsl:attribute>

      <xsl:for-each select="TestCase">
        <testcase>
          <xsl:attribute name="name">
            <xsl:value-of select="@name"/>
          </xsl:attribute>
          <xsl:if test="@result!='passed'">
            <failure>See log file.</failure>
          </xsl:if>
        </testcase>
      </xsl:for-each>
    </testsuite>
  </xsl:template>
</xsl:stylesheet>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文