Skip to content

Commit

Permalink
Enable customization of testng-results.xml
Browse files Browse the repository at this point in the history
Closes testng-team#2171

In order for one to be able to generate their 
own customized version of testng-results.xml
without a lot of code duplication, the following
should be done.

1. Extend org.testng.reporters.XMLReporter
2. Override “fileName()” method and provide your
own file name.
3. Override “addCustomTagsFor()” method and plugin
your implementation which will add one or more tags
to the xml file.
4. Add the newly created class as one of the listeners
via “@listeners” annotation or via “<listeners>” 
tag or via SPI approach.


For a sample of how the customized listener 
can look like, take a look at the sample 
that resides in 
“src/test/java/test/reports/issue2171/MyExampleListener.java”
  • Loading branch information
krmahadevan committed Oct 13, 2019
1 parent 194eb64 commit 993c8c9
Show file tree
Hide file tree
Showing 7 changed files with 89 additions and 6 deletions.
1 change: 1 addition & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Current
Fixed: GITHUB-2171: Ability to embed attachments and make them available on TestNG XML report (Krishnan Mahadevan)
Fixed: GITHUB-2152: Multiple Test Groups Causing @BeforeMethod and @AfterMethod to be called multiple times for a single test (Krishnan Mahadevan)
Fixed: GITHUB-2172: Suite summary report table issue with EmailableReporter2.java (Devendra Raju K)
Fixed: GITHUB-2148: TestNG - configfailurepolicy=“continue” is not working for retried test (Krishnan Mahadevan)
Expand Down
15 changes: 15 additions & 0 deletions src/main/java/org/testng/reporters/ICustomizeXmlReport.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package org.testng.reporters;

import org.testng.ITestResult;

/**
* An interface that helps add custom xml tags to the TestNG generated xml report.
*/
public interface ICustomizeXmlReport {

/**
* @param xmlBuffer - An {@link XMLStringBuffer} object that represents the buffer to be used.
* @param testResult - An {@link ITestResult} object that represents a test method's result.
*/
void addCustomTagsFor(XMLStringBuffer xmlBuffer, ITestResult testResult);
}
10 changes: 7 additions & 3 deletions src/main/java/org/testng/reporters/XMLReporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
import java.util.Set;

/** The main entry for the XML generation operation */
public class XMLReporter implements IReporter {
public class XMLReporter implements IReporter, ICustomizeXmlReport {

private final XMLReporterConfig config = new XMLReporterConfig();
private XMLStringBuffer rootBuffer;
Expand Down Expand Up @@ -79,7 +79,11 @@ public void generateReport(
Utils.writeUtf8File(config.getOutputDirectory(), fileName(), rootBuffer, null /* no prefix */);
}

private static String fileName() {
public void addCustomTagsFor(XMLStringBuffer xmlBuffer, ITestResult testResult) {

}

public String fileName() {
return RuntimeBehavior.getDefaultFileNameForXmlReports();
}

Expand Down Expand Up @@ -136,7 +140,7 @@ private void writeSuiteToBuffer(XMLStringBuffer xmlBuffer, ISuite suite) {
writeSuiteGroups(xmlBuffer, suite);

Map<String, ISuiteResult> results = suite.getResults();
XMLSuiteResultWriter suiteResultWriter = new XMLSuiteResultWriter(config);
XMLSuiteResultWriter suiteResultWriter = new XMLSuiteResultWriter(config, this);
for (Map.Entry<String, ISuiteResult> result : results.entrySet()) {
suiteResultWriter.writeSuiteResult(xmlBuffer, result.getValue());
}
Expand Down
7 changes: 5 additions & 2 deletions src/main/java/org/testng/reporters/XMLSuiteResultWriter.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,10 +32,12 @@
*/
public class XMLSuiteResultWriter {

private XMLReporterConfig config;
private final XMLReporterConfig config;
private final ICustomizeXmlReport customizer;

public XMLSuiteResultWriter(XMLReporterConfig config) {
public XMLSuiteResultWriter(XMLReporterConfig config, ICustomizeXmlReport customizer) {
this.config = config;
this.customizer = customizer;
}

/**
Expand Down Expand Up @@ -159,6 +161,7 @@ private void addTestResult(XMLStringBuffer xmlBuffer, ITestResult testResult) {
if (config.isGenerateTestResultAttributes()) {
addTestResultAttributes(xmlBuffer, testResult);
}
customizer.addCustomTagsFor(xmlBuffer, testResult);
xmlBuffer.pop();
}

Expand Down
20 changes: 19 additions & 1 deletion src/test/java/test/reports/XmlReporterTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
import java.io.IOException;
import java.util.UUID;
import java.util.regex.Pattern;
import test.reports.issue2171.TestClassExample;

import static org.assertj.core.api.Assertions.assertThat;

Expand Down Expand Up @@ -52,12 +53,29 @@ public void ensureStackTraceHasLineFeedsTest() throws Exception {
.isGreaterThan(1);
}

@Test(description = "GITHUB-2171")
public void ensureCustomisationOfReportIsSupported() throws Exception {
File file = runTest(TestClassExample.class, "issue_2171.xml");
DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
DocumentBuilder builder = factory.newDocumentBuilder();
Document doc = builder.parse(file);
XPath xPath = XPathFactory.newInstance().newXPath();
String expression = "//test/class/test-method/file/@path";
String data = (String) xPath.compile(expression).evaluate(doc, XPathConstants.STRING);
assertThat(data.trim()).isEqualTo("issue2171.html");
}

private static File runTest(Class<?> clazz) {
return runTest(clazz, RuntimeBehavior.FILE_NAME);
}

private static File runTest(Class<?> clazz, String fileName) {
String suiteName = UUID.randomUUID().toString();
File fileLocation = createDirInTempDir(suiteName);
TestNG testng = create(fileLocation.toPath(), clazz);
testng.setUseDefaultListeners(true);
testng.run();
return new File(fileLocation, RuntimeBehavior.FILE_NAME);
return new File(fileLocation, fileName);

}
}
24 changes: 24 additions & 0 deletions src/test/java/test/reports/issue2171/MyExampleListener.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
package test.reports.issue2171;

import java.util.Properties;
import org.testng.ITestResult;
import org.testng.reporters.XMLReporter;
import org.testng.reporters.XMLStringBuffer;

public class MyExampleListener extends XMLReporter {

@Override
public String fileName() {
return "issue_2171.xml";
}

@Override
public void addCustomTagsFor(XMLStringBuffer xmlBuffer, ITestResult testResult) {
Properties props = new Properties();
for (String attributeName : testResult.getAttributeNames()) {
props.setProperty("path", testResult.getAttribute(attributeName).toString());
xmlBuffer.push(attributeName, props);
xmlBuffer.pop(attributeName);
}
}
}
18 changes: 18 additions & 0 deletions src/test/java/test/reports/issue2171/TestClassExample.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package test.reports.issue2171;

import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.annotations.Listeners;
import org.testng.annotations.Test;


@Listeners(MyExampleListener.class)
public class TestClassExample {

@Test
public void testMethod() {
ITestResult result = Reporter.getCurrentTestResult();
result.setAttribute("file", "issue2171.html");
}

}

0 comments on commit 993c8c9

Please sign in to comment.