I'm writing an xslt for the trx file of mstest.
Apart from knowing the results of the entire session, I'd also like to know the number of successes and failures for each class.
I've tried out many ways, but i'm not able to get the results for a particular class.
This is how the xml looks.
(edit)
<TestRun>
<ResultSummary outcome="Completed">
<Counters total="2" passed="2" error="0" failed="0" inconclusive="0" />
</ResultSummary>
<TestDefinitions>
<UnitTest name="NullUserIdInConstructor" id="e58f837c-2116-ce69-bf31-1fe6beec73d3">
<TestMethod className="TestProject1.Test.LogonInfoTest, TestProject1.Test" name="NullUserIdInConstructor" />
</UnitTest>
<UnitTest name="LogonInfoConstructorTest" id="b9bbb3b6-cc0b-7f4d-276e-16c52b0814c6">
<TestMethod className="TestProject1.Test.LogonInfoTest, TestProject1.Test" name="LogonInfoConstructorTest" />
</UnitTest>
</TestDefinitions>
<Results>
<UnitTestResult testId="b9bbb3b6-cc0b-7f4d-276e-16c52b0814c6" testName="LogonInfoConstructorTest" outcome="Passed" >
</UnitTestResult>
<UnitTestResult testId="e58f837c-2116-ce69-bf31-1fe6beec73d3" testName="NullUserIdInConstructor" outcome="Passed" >
</UnitTestResult>
</Results>
</TestRun>
Here's a sample of the required output.
<table>
<tr>
<td>Test Name</td>
<td>Result</td>
<td>Duration</td>
<td>Passed</td>
<td>Failed</td>
<td>Inconclusive</td>
</tr>
<tr>
<td colspan="3">This is the Class Name</td>
<td>2</td>
<td>0</td>
<td>0</td>
</tr>
<tr>
<td>LogonInfoConstructorTest</td>
<td>Passed</td>
<td>00:00:00.0234997</td>
</tr>
<tr>
<td>NullUserIdInConstructor</td>
<td>Passed</td>
<td>00:00:00.0047344</td>
</tr>
</table>
I'm getting the className
attribute from //UnitTest/TestMethod
, getting the correspoding id
from //UnitTest
and then matching it with //UnitTestResult[@testId]
to get the corresponding value of the outcome
attribute. But I'm not able to accomplish my requirement. I'm not sure where I'm going wrong.
This sample has only 1 class. but the actual file I'm working on has many classes.
Thanks in advance.
(edit2) Here's a part of the xsl I'm currently using.
<xsl:key name="class-key" match="@className" use="."/>
<xsl:key name="class" match="t:TestMethod" use="@className"/>
<xsl:key name="result" match="t:UnitTestResult" use="@testName"/>
<xsl:variable name="unique-classes" select="//t:TestMethod/@className[generate-id(.)=generate-id(key('class-key',.))]" />
<xsl:template name="details2">
<h3>Unit Test Results</h3>
<table>
<tr>
<td></td>
<td>Test Name</td>
<td>Result</td>
<td>Duration</td>
</tr>
<xsl:for-each select="$unique-classes">
<xsl:sort />
<xsl:variable name="curClass" select="."/>
<xsl:variable name="parentId" select="generate-id(./..)" />
<xsl:variable name="currentId" select="generate-id(.)" />
<tr id="{$parentId}">
<td id="{$currentId}"
style="font-weight:bold; cursor:pointer;"
onClick="toggleDetail(this)">[+]</td>
<xsl:call-template name="groups" />
</tr>
<xsl:call-template name="classRunsDetail">
<xsl:with-param name="curClass" select="."/>
</xsl:call-template>
<tr id="{$currentId}-end" style="display:none;">
<td style="border-bottom:0px solid black;height:1px;background-color:black" colspan="4"></td>
</tr>
</xsl:for-each>
</table>
</xsl:template>
<xsl:template name="classRunsDetail">
<xsl:param name="curClass"/>
<xsl:variable name="parentId" select="generate-id(.)" />
<xsl:for-each select="//t:UnitTest/t:TestMethod[@className=$curClass]">
<xsl:sort select="@name"/>
<xsl:variable name="testid" select="../@id"/>
<xsl:for-each select="//t:UnitTestResult[@testId=$testid]">
<tr id="{$parentId}">
<td></td>
<td>
<xsl:value-of select="@testName"/>
</td>
<td>
<xsl:choose>
<xsl:when test="@outcome = $fail">FAILED</xsl:when>
<xsl:when test="@outcome = $pass">Passed</xsl:when>
<xsl:when test="@outcome = $incon">Not Run</xsl:when>
<xsl:otherwise>Error</xsl:otherwise>
</xsl:choose>
</td>
<td>
<xsl:value-of select="@duration"/>
</td>
</tr>
</xsl:for-each>
</xsl:for-each>
</xsl:template>
<xsl:template name="groups" match="t:TestMethod[count(.|key('class',@className)[1])=1]">
<xsl:variable name="result" select="key('result',key('class',@className)/@name)"/>
<td valign="bottom" style="background-color:beige;font-weight:bold;" colspan="3">
<xsl:value-of select="key('class', @className)[1]"/>
</td>
<td>
<xsl:value-of select="count($result[@outcome='Passed'])"/>
</td>
<td>
<xsl:value-of select="count($result[@outcome='Failed'])"/>
</td>
<td>
<xsl:value-of select="count($result[@outcome='Inconclusive'])"/>
</td>
<xsl:apply-templates select="key('class',@className)" mode="sub"/>
</xsl:template>
Sorry for the huge code input. But I'm actually using javascript to slide down the test names when a particular class is clicked. So I need so many templates. Am I missing something in the code..