Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
org.testng.reporters.JUnitReportReporter Maven / Gradle / Ivy
package org.testng.reporters;
import java.io.File;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.text.DecimalFormat;
import java.text.DecimalFormatSymbols;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import org.testng.IReporter;
import org.testng.ISuite;
import org.testng.ISuiteResult;
import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.collections.ListMultiMap;
import org.testng.collections.Lists;
import org.testng.collections.Maps;
import org.testng.collections.SetMultiMap;
import org.testng.collections.Sets;
import org.testng.internal.Utils;
import org.testng.xml.XmlSuite;
public class JUnitReportReporter implements IReporter {
@Override
public void generateReport(
List xmlSuites, List suites, String defaultOutputDirectory) {
Map, Set> results = Maps.newHashMap();
ListMultiMap befores = Maps.newListMultiMap();
ListMultiMap afters = Maps.newListMultiMap();
SetMultiMap, ITestNGMethod> mapping = new SetMultiMap<>(false);
for (ISuite suite : suites) {
Map suiteResults = suite.getResults();
addMapping(mapping, suite.getExcludedMethods());
for (ISuiteResult sr : suiteResults.values()) {
ITestContext tc = sr.getTestContext();
addResults(tc.getPassedTests().getAllResults(), results);
addResults(tc.getFailedTests().getAllResults(), results);
addResults(tc.getSkippedTests().getAllResults(), results);
addResults(tc.getFailedConfigurations().getAllResults(), results);
for (ITestResult tr : tc.getPassedConfigurations().getAllResults()) {
if (tr.getMethod().isBeforeMethodConfiguration()) {
befores.put(tr.getInstance(), tr);
}
if (tr.getMethod().isAfterMethodConfiguration()) {
afters.put(tr.getInstance(), tr);
}
}
}
}
final String hostname = getHostName();
for (Map.Entry, Set> entry : results.entrySet()) {
Class> cls = entry.getKey();
Properties p1 = new Properties();
p1.setProperty(XMLConstants.ATTR_NAME, cls.getName());
p1.setProperty(XMLConstants.ATTR_TIMESTAMP, JUnitXMLReporter.formattedTime());
List testCases = Lists.newArrayList();
int failures = 0;
int errors = 0;
int skipped = 0;
int testCount = 0;
float totalTime = 0;
Collection iTestResults = sort(entry.getValue());
for (ITestResult tr : iTestResults) {
long time = tr.getEndMillis() - tr.getStartMillis();
time += getNextConfiguration(befores, tr);
time += getNextConfiguration(afters, tr);
Throwable t = tr.getThrowable();
switch (tr.getStatus()) {
case ITestResult.SKIP:
case ITestResult.SUCCESS_PERCENTAGE_FAILURE:
skipped++;
break;
case ITestResult.FAILURE:
if (t instanceof AssertionError) {
failures++;
} else {
errors++;
}
break;
}
totalTime += time;
testCount++;
TestTag testTag = createTestTagFor(tr, cls);
testTag.properties.setProperty(XMLConstants.ATTR_TIME, "" + formatTime(time));
testCases.add(testTag);
}
int ignored = getDisabledTestCount(mapping.get(entry.getKey()));
for (ITestNGMethod eachMethod : mapping.get(entry.getKey())) {
testCases.add(createIgnoredTestTagFor(eachMethod));
}
p1.setProperty(XMLConstants.ATTR_FAILURES, Integer.toString(failures));
p1.setProperty(XMLConstants.ATTR_ERRORS, Integer.toString(errors));
p1.setProperty(XMLConstants.SKIPPED, Integer.toString(skipped + ignored));
p1.setProperty(XMLConstants.ATTR_NAME, cls.getName());
p1.setProperty(XMLConstants.ATTR_TESTS, Integer.toString(testCount + ignored));
p1.setProperty(XMLConstants.ATTR_TIME, "" + formatTime(totalTime));
if (hostname != null) {
p1.setProperty(XMLConstants.ATTR_HOSTNAME, hostname);
}
//
// Now that we have all the information we need, generate the file
//
XMLStringBuffer xsb = new XMLStringBuffer();
xsb.addComment("Generated by " + getClass().getName());
xsb.push(XMLConstants.TESTSUITE, p1);
for (TestTag testTag : testCases) {
boolean testCaseHasChildElements = testTag.childTag != null || testTag.sysOut != null;
if (putElement(xsb, XMLConstants.TESTCASE, testTag.properties, testCaseHasChildElements)) {
if (testTag.childTag != null) {
Properties p = new Properties();
safeSetProperty(p, XMLConstants.ATTR_MESSAGE, testTag.message);
safeSetProperty(p, XMLConstants.ATTR_TYPE, testTag.type);
if (putElement(xsb, testTag.childTag, p, testTag.stackTrace != null)) {
xsb.addCDATA(testTag.stackTrace);
xsb.pop(testTag.childTag);
}
}
// Add reporter output for each test case as a child system-out element of testcase.
if (testTag.sysOut != null) {
putElement(xsb, XMLConstants.SYSTEM_OUT, new Properties(), true);
xsb.addCDATA(testTag.sysOut);
xsb.pop(XMLConstants.SYSTEM_OUT);
}
xsb.pop(XMLConstants.TESTCASE);
}
}
// Add the full reporter output once as a child system-out element of testsuite.
List output = Reporter.getOutput();
if ((!output.isEmpty())) {
putElement(xsb, XMLConstants.SYSTEM_OUT, new Properties(), true);
xsb.addCDATA(String.join("\n", output));
xsb.pop(XMLConstants.SYSTEM_OUT);
}
xsb.pop(XMLConstants.TESTSUITE);
String outputDirectory = defaultOutputDirectory + File.separator + "junitreports";
Utils.writeUtf8File(outputDirectory, getFileName(cls), xsb.toXML());
}
}
private static Collection sort(Set results) {
List sortedResults = new ArrayList<>(results);
sortedResults.sort(Comparator.comparingInt(o -> o.getMethod().getPriority()));
return Collections.unmodifiableList(sortedResults);
}
private static String getHostName() {
try {
return InetAddress.getLocalHost().getHostName();
} catch (UnknownHostException e) {
// ignore
return null;
}
}
private static int getDisabledTestCount(Set methods) {
int count = 0;
for (ITestNGMethod method : methods) {
if (!method.getEnabled()) {
count = count + 1;
}
}
return count;
}
private TestTag createIgnoredTestTagFor(ITestNGMethod method) {
TestTag testTag = new TestTag();
Properties p2 = new Properties();
p2.setProperty(XMLConstants.ATTR_CLASSNAME, method.getRealClass().getName());
p2.setProperty(XMLConstants.ATTR_NAME, method.getMethodName());
testTag.childTag = XMLConstants.SKIPPED;
testTag.properties = p2;
return testTag;
}
private TestTag createTestTagFor(ITestResult tr, Class> cls) {
TestTag testTag = new TestTag();
Properties p2 = new Properties();
p2.setProperty(XMLConstants.ATTR_CLASSNAME, cls.getName());
p2.setProperty(XMLConstants.ATTR_NAME, getTestName(tr));
int status = tr.getStatus();
if (status == ITestResult.SKIP || status == ITestResult.SUCCESS_PERCENTAGE_FAILURE) {
testTag.childTag = XMLConstants.SKIPPED;
} else if (status == ITestResult.FAILURE) {
handleFailure(testTag, tr.getThrowable());
}
List output = Reporter.getOutput(tr);
if (!output.isEmpty()) {
testTag.sysOut = String.join("\n", output);
}
testTag.properties = p2;
return testTag;
}
private static void handleFailure(TestTag testTag, Throwable t) {
testTag.childTag = t instanceof AssertionError ? XMLConstants.FAILURE : XMLConstants.ERROR;
if (t != null) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
t.printStackTrace(pw);
testTag.message = t.getMessage();
testTag.type = t.getClass().getName();
testTag.stackTrace = sw.toString();
}
}
/** Put a XML start or empty tag to the XMLStringBuffer depending on hasChildElements parameter */
private boolean putElement(
XMLStringBuffer xsb, String tagName, Properties attributes, boolean hasChildElements) {
if (hasChildElements) {
xsb.push(tagName, attributes);
} else {
xsb.addEmptyElement(tagName, attributes);
}
return hasChildElements;
}
/** Set property if value is non-null */
private void safeSetProperty(Properties p, String key, String value) {
if (value != null) {
p.setProperty(key, value);
}
}
/**
* Add the time of the configuration method to this test method.
*
* The only problem with this method is that the timing of a test method might not be added to
* the time of the same configuration method that ran before it but since they should all be
* equivalent, this should never be an issue.
*/
private long getNextConfiguration(
ListMultiMap configurations, ITestResult tr) {
long result = 0;
List confResults = configurations.get(tr.getInstance());
Map seen = Maps.newHashMap();
for (ITestResult r : confResults) {
if (!seen.containsKey(r.getMethod())) {
result += r.getEndMillis() - r.getStartMillis();
seen.put(r.getMethod(), r);
}
}
confResults.removeAll(seen.values());
return result;
}
protected String getFileName(Class cls) {
return "TEST-" + cls.getName() + ".xml";
}
protected String getTestName(ITestResult tr) {
return tr.getMethod().getMethodName();
}
private String formatTime(float time) {
DecimalFormatSymbols symbols = new DecimalFormatSymbols();
// JUnitReports wants points here, regardless of the locale
symbols.setDecimalSeparator('.');
DecimalFormat format = new DecimalFormat("#.###", symbols);
format.setMinimumFractionDigits(3);
return format.format(time / 1000.0f);
}
private static class TestTag {
Properties properties;
String message;
String type;
String stackTrace;
String childTag;
String sysOut;
}
private void addResults(Set allResults, Map, Set> out) {
for (ITestResult tr : allResults) {
Class> cls = tr.getMethod().getTestClass().getRealClass();
Set l = out.computeIfAbsent(cls, k -> Sets.newHashSet());
l.add(tr);
}
}
private void addMapping(
SetMultiMap, ITestNGMethod> mapping, Collection methods) {
for (ITestNGMethod method : methods) {
if (!method.getEnabled()) {
mapping.put(method.getRealClass(), method);
}
}
}
}