7 JUnit
meleu edited this page 2022-05-25 13:40:00 -03:00

Getting JUnit XML from ShellCheck

ShellCheck does not have a JUnit XML formatter, but at the end of this article you can find checkstyle2junit.xslt, an XSLT program that converts from CheckStyle's XML output to JUnit's XML.

Here's ShellCheck's (CheckStyle-compatible) XML output:

$ shellcheck -f checkstyle foo.bash bar.bash

<?xml version='1.0' encoding='UTF-8'?>
<checkstyle version='4.3'>
<file name='foo.bash' >
<error line='1' column='1' severity='error' message='Tips depend on target shell and yours is unknown. Add a shebang.' source='ShellCheck.SC2148' />
<error line='1' column='6' severity='info' message='Double quote to prevent globbing and word splitting.' source='ShellCheck.SC2086' />
</file>
<file name='bar.bash'>
</file>
</checkstyle>

Here it is with the XSLT applied using xmlstarlet:

$ shellcheck -f checkstyle foo.bash bar.bash | xmlstarlet tr checkstyle2junit.xslt

<?xml version="1.0" encoding="UTF-8"?>
<testsuite tests="2" failures="2">
<testcase classname="foo.bash" name="foo.bash">
<failure type="ShellCheck.SC2148">Line 1: Tips depend on target shell and yours is unknown. Add a shebang. See https://www.shellcheck.net/wiki/SC2148</failure>
<failure type="ShellCheck.SC2086">Line 1: Double quote to prevent globbing and word splitting. See https://www.shellcheck.net/wiki/SC2086</failure>
</testcase>
<testcase classname="bar.bash" name="bar.bash">
</testcase>
</testsuite>

checkstyle2junit.xslt

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output encoding="UTF-8" method="xml"></xsl:output>

  <xsl:template match="/">
    <testsuite>
      <xsl:attribute name="tests">
        <xsl:value-of select="count(.//file)" />
      </xsl:attribute>
      <xsl:attribute name="failures">
        <xsl:value-of select="count(.//error)" />
      </xsl:attribute>
      <xsl:for-each select="//checkstyle">
        <xsl:apply-templates />
      </xsl:for-each>
    </testsuite>
  </xsl:template>

  <xsl:template match="file">
    <testcase>
      <xsl:attribute name="classname">
        <xsl:value-of select="@name" />
      </xsl:attribute>
      <xsl:attribute name="name">
        <xsl:value-of select="@name" />
      </xsl:attribute>
      <xsl:apply-templates select="node()" />
    </testcase>
  </xsl:template>

  <xsl:template match="error">
    <failure>
      <xsl:attribute name="type">
        <xsl:value-of select="@source" />
      </xsl:attribute>
      <xsl:text>Line </xsl:text>
      <xsl:value-of select="@line" />
      <xsl:text>: </xsl:text>
      <xsl:value-of select="@message" />
      <xsl:text> See https://www.shellcheck.net/wiki/</xsl:text>
      <xsl:value-of select="substring(@source, '12')" />
    </failure>
  </xsl:template>
</xsl:stylesheet>