Search code examples
xsltcontinuous-integrationcruisecontrol.netbambooboost-test

Anyone have an XSL to convert Boost.Test XML logs to a presentable format?


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!


Solution

  • 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.