Reputation: 616
Each class has 3 or more test methods.
Each test method can pass or fail.
Zero, one or more methods can fail.
The requirement is to traverse through the test-method results, and when a failed method (first match) is found, get the attribute value of 'message' and print it.
If none of the methods failed, then, print blank.
How can I achieve this?
Input.xml
<testng-results>
<suite>
<test>
<class name="activities.ActivitiesListTest">
<test-method status="PASS" started-at="2019-02-07T18:24:47Z" name="initTest">
<reporter-output>
</reporter-output>
</test-method>
<test-method status="FAIL" started-at="2019-02-07T18:24:47Z" name="ActListsForContactShowsContactRelatedTasksTest">
<exception class="org.openqa.selenium.NoSuchElementException">
<message>
<![CDATA[Element with locator 123 not present']]>
</message>
</exception>
<reporter-output>
</reporter-output>
</test-method>
<test-method status="FAIL" started-at="2019-02-07T18:24:47Z" name="afterClass">
<exception class="org.openqa.selenium.NoSuchElementException">
<message>
<![CDATA[Message 3]]>
</message>
</exception>
<reporter-output>
</reporter-output>
</test-method>
</class>
</test>
</suite>
</testng-results>
Expected Result:
<Suite>
<test failed_reason=" <![CDATA[Element with locator 123 not
present']]>"/>
</Suite>
Tried (XSL):
<Suite>
<xsl:for-each select="/class">
<test>
<xsl:attribute name="failed_reason">
<xsl:choose>
<xsl:when test="*[@status='FAIL']">test-method[position() = current()]/exception/@message</xsl:when>
</xsl:choose>
</xsl:attribute>
</test>
</xsl:for-each>
</Suite>
Sample absolute path of exception message:
suite/test/class[@name='ActivitiesListForContactShowsContactRelatedTasksTest']/test-method[@name='ActListsTest']/exception/message
But, didn't work.
How to achieve the expected result?
EDIT: Trying Michael's solution.
This is how my XSL currently looks like:
<xsl:template match="/">
<Suite>
<xsl:for-each select="testng-results/suite/test/class">
<test>
<xsl:attribute name="start-time">
<xsl:value-of select="test-method[1]/@started-at"/>
</xsl:attribute>
<xsl:attribute name="failed_reason">
{normalize-space(test-method[@status='FAIL'][1]/exception/message)}
</xsl:attribute>
</test>
</xsl:for-each>
</Suite>
</xsl:template>
Upvotes: 0
Views: 83
Reputation: 116959
I am guessing (!) you want to do something like:
<xsl:template match="/*">
<Suite>
<xsl:for-each select="class">
<test failed_reason="{normalize-space(test-method[@status='FAIL'][1]/exception/message)}"/>
</xsl:for-each>
</Suite>
</xsl:template>
Note:
<xsl:for-each select="/class">
will not select anything unless class
is the root element. But if class
is the root element, then there is only one class - so there's no point in using xsl:for-each
.
Upvotes: 1