Custom Junit Report

Custom JUnit Report?

The junitreport task uses XSLT to produce the report from the XML files generated by the junittask.

You can customize the output by specifying your own XSLT using the styledir attribute of the nested report element:

<!-- use reportstyle/junit-frames.xsl to produce the report -->
<report styledir="reportstyle" format="frames" todir="testreport"/>

For customizing the the output, one option would be to make a copy of the default XSLT and modify that. Or you could look for an alternative XSLT which is more easy to customize for your purposes.

For small changes, it might be easiest to just import the default XSLT and override whatever templates you need to customize. For example, to add a column for each test, you would need to override the template which produces the table header and the template which produces a table row. Below, I have just copied those templates and modified them a bit to add one column (look for two additions marked with <!-- ADDED -->).

<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

<!-- import the default stylesheet -->
<xsl:import href="jar:file:lib/ant-junit.jar!/org/apache/tools/ant/taskdefs/optional/junit/xsl/junit-frames.xsl"/>

<!-- override the template producing the test table header -->
<xsl:template name="testcase.test.header">
<xsl:param name="show.class" select="''"/>
<tr valign="top">
<xsl:if test="boolean($show.class)">
<th>Class</th>
</xsl:if>
<th>Name</th>
<th>Status</th>
<th width="80%">Type</th>
<th nowrap="nowrap">Time(s)</th>

<!-- ADDED -->
<th>Screenshot</th>

</tr>
</xsl:template>

<!-- override the template producing a test table row -->
<xsl:template match="testcase" mode="print.test">
<xsl:param name="show.class" select="''"/>
<tr valign="top">
<xsl:attribute name="class">
<xsl:choose>
<xsl:when test="error">Error</xsl:when>
<xsl:when test="failure">Failure</xsl:when>
<xsl:otherwise>TableRowColor</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
<xsl:variable name="class.href">
<xsl:value-of select="concat(translate(../@package,'.','/'), '/', ../@id, '_', ../@name, '.html')"/>
</xsl:variable>
<xsl:if test="boolean($show.class)">
<td><a href="{$class.href}"><xsl:value-of select="../@name"/></a></td>
</xsl:if>
<td>
<a name="{@name}"/>
<xsl:choose>
<xsl:when test="boolean($show.class)">
<a href="{concat($class.href, '#', @name)}"><xsl:value-of select="@name"/></a>
</xsl:when>
<xsl:otherwise>
<xsl:value-of select="@name"/>
</xsl:otherwise>
</xsl:choose>
</td>
<xsl:choose>
<xsl:when test="failure">
<td>Failure</td>
<td><xsl:apply-templates select="failure"/></td>
</xsl:when>
<xsl:when test="error">
<td>Error</td>
<td><xsl:apply-templates select="error"/></td>
</xsl:when>
<xsl:otherwise>
<td>Success</td>
<td></td>
</xsl:otherwise>
</xsl:choose>
<td>
<xsl:call-template name="display-time">
<xsl:with-param name="value" select="@time"/>
</xsl:call-template>
</td>

<!-- ADDED -->
<td>
<a href="link/to/screenshot/for/test/{@name}">screenshot</a>
</td>

</tr>
</xsl:template>

</xsl:stylesheet>

Here's how the result looks like:

screenshot

Customize Junit 4 XML report

How is this XML report generated by JUnit and Gradle?

It’s eventually generated by the Gradle internal class org.gradle.api.internal.tasks.testing.junit.result.JUnitXmlResultWriter.

Basically, I want to add custom attribute to every executed method.

<testcase name="test_test_something" classname="some.class.name" time="0.069" my-own-attribute="somevalue"/>

[…]
Is there a way to modify this process of report generation to add custom data to the report while doing minimal changes?

Unfortunately, there is no way to add further attributes to the <testcase/> element. This code shows how the element and its attributes are currently created; there is no way to hook into that creation process.


If you can live with a hacky solution, then you could try writing your custom data to StdOut/StdErr during the test and set the outputPerTestCase property as follows:

// (configuring the default `test` task of the `java` plugin here; works with
// any task of Gradle’s `Test` type, though)
test {
reports {
junitXml {
outputPerTestCase = true
}
}
}

The written output will then end up at least somewhere within the <testcase/> element and you might be able use it from there somehow.



Related Topics



Leave a reply



Submit