Tag Archives: unittest

C UnitTests with Check, and reporting in Jenkins/Hudson

Update 20110910 – This is now available as a standard feature in the current xUnit plugin for Jenkins/Hudson.

I’ve gotten quite spoilt over the years with things like Jenkins/Hudson, and automated test tools magically creating output that Jenkins understands, and magically creating pretty graphs and charts. But that is working in Java and python, where unit tests are common and easy. Working in raw C, this isn’t quite so common, nor quite so easy. I’ve been wanting to add unit testing to my C code for a while, and with a new task at hand, and having finally gotten Jenkins set up, it was time to get this done

I found http://stackoverflow.com/questions/65820/unit-testing-c-code and given the number of votes, gave Check a go. I had a few niggles with makefiles and library load paths and so on, (Isn’t C coding fun?) but then it was beautifully and happily giving me nice output on the command line.

XML output for Jenkins was another story. Check supports XML output, with just a single line of config in the test suite, but it’s yet another format. The regular standard JUnit plugin didn’t recognise it, and the xUnit plugin, depsite supporting almost a dozen other tools outputs, didn’t support Check. So much for Check being big and popular. However, the xUnit plugin does support applying a custom XSL stylesheet to your tool’s results. So I made a basic XSL for converting Check’s results into something compatible. And now I have pretty charts and graphs for my raw C code too. Whee

 
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ck="http://check.sourceforge.net/ns"
exclude-result-prefixes="ck"> 
   <xsl:output method="xml" indent="yes"/> 
 
<xsl:variable name="checkCount" select="count(//ck:suite/ck:test)"/>
<xsl:variable name="checkCountFailure"
select="count(//ck:suite/ck:test[@result='failure'])"/>
<xsl:variable name="suitename" select="//ck:suite/ck:title"/>
 
<xsl:template match="/"> 
      <testsuite> 
         <xsl:attribute name="errors">0</xsl:attribute>
         <xsl:attribute name="tests"> 
          <xsl:value-of select="$checkCount"/> 
         </xsl:attribute> 
         <xsl:attribute name="failures"> 
          <xsl:value-of select="$checkCountFailure"/> 
         </xsl:attribute> 
         <xsl:attribute name="name"> 
            <xsl:value-of select="$suitename" /> 
         </xsl:attribute> 
         <xsl:apply-templates /> 
      </testsuite> 
   </xsl:template> 
 
<xsl:template match="//ck:suite/ck:test">
    <testcase>
      <xsl:attribute name="name">
        <xsl:value-of select="./ck:id"/>
      </xsl:attribute>
      <xsl:attribute name="classname">
        <xsl:value-of select="$suitename" /> 
      </xsl:attribute>
      <xsl:attribute name="time">0</xsl:attribute>
      <xsl:if test="@result = 'failure'">
        <error type="error">
          <xsl:attribute name="message">
            <xsl:value-of select="./ck:message"/>
          </xsl:attribute>
        </error>
      </xsl:if>
    </testcase>
</xsl:template>
 
<!-- this swallows all unmatched text -->
<xsl:template match="text()|@*" /> 
</xsl:stylesheet>

Known issues:

  • Check reports the duration of the entire testsuite. Junit expects a time per test. I tried putting the duration element from Check on the top level suite, but Jenkins ignored it.
  • The “classname” is a bit funky, but so be it.

JENKINS-10909 is tracking this as a feature over on their issue tracker.

As a friend said, “xml is just like violence. if it’s not solving your problem, use more.”