org.testng.reporters.EmailableReporter Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of testng Show documentation
Show all versions of testng Show documentation
Testing framework for Java
package org.testng.reporters;
import org.testng.IInvokedMethod;
import org.testng.IReporter;
import org.testng.IResultMap;
import org.testng.ISuite;
import org.testng.ISuiteResult;
import org.testng.ITestClass;
import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.ITestResult;
import org.testng.Reporter;
import org.testng.collections.Lists;
import org.testng.internal.Utils;
import org.testng.log4testng.Logger;
import org.testng.xml.XmlSuite;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import static java.nio.charset.StandardCharsets.UTF_8;
import static java.nio.file.Files.newBufferedWriter;
/**
* Reported designed to render self-contained HTML top down view of a testing suite.
*
* @since 5.2
*/
public class EmailableReporter implements IReporter {
private static final Logger L = Logger.getLogger(EmailableReporter.class);
// ~ Instance fields ------------------------------------------------------
private PrintWriter m_out;
private int m_row;
private Integer m_testIndex;
private int m_methodIndex;
private String fileName = "emailable-report.html";
public String getFileName() {
return fileName;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
// ~ Methods --------------------------------------------------------------
/** Creates summary of the run */
@Override
public void generateReport(List xml, List suites, String outdir) {
try {
m_out = createWriter(outdir);
} catch (IOException e) {
L.error("output file", e);
return;
}
startHtml(m_out);
generateSuiteSummaryReport(suites);
generateMethodSummaryReport(suites);
generateMethodDetailReport(suites);
endHtml(m_out);
m_out.flush();
m_out.close();
}
protected PrintWriter createWriter(String outdir) throws IOException {
new File(outdir).mkdirs();
String jvmArg = RuntimeBehavior.getDefaultEmailableReportName();
if (jvmArg != null && !jvmArg.trim().isEmpty()) {
fileName = jvmArg;
}
return new PrintWriter(newBufferedWriter(new File(outdir, fileName).toPath(), UTF_8));
}
/** Creates a table showing the highlights of each test method with links to the method details */
protected void generateMethodSummaryReport(List suites) {
m_methodIndex = 0;
startResultSummaryTable();
int testIndex = 1;
for (ISuite suite : suites) {
if (suites.size() > 1) {
titleRow(suite.getName(), 5);
}
Map r = suite.getResults();
for (ISuiteResult r2 : r.values()) {
ITestContext testContext = r2.getTestContext();
String testName = testContext.getName();
m_testIndex = testIndex;
resultSummary(
suite,
testContext.getFailedConfigurations(),
testName,
"failed",
" (configuration methods)");
resultSummary(suite, testContext.getFailedTests(), testName, "failed", "");
resultSummary(
suite,
testContext.getSkippedConfigurations(),
testName,
"skipped",
" (configuration methods)");
resultSummary(suite, testContext.getSkippedTests(), testName, "skipped", "");
resultSummary(suite, testContext.getPassedTests(), testName, "passed", "");
testIndex++;
}
}
m_out.println("");
}
/** Creates a section showing known results for each method */
protected void generateMethodDetailReport(List suites) {
m_methodIndex = 0;
for (ISuite suite : suites) {
Map r = suite.getResults();
for (ISuiteResult r2 : r.values()) {
ITestContext testContext = r2.getTestContext();
if (r.values().size() > 0) {
m_out.println("" + testContext.getName() + "
");
}
resultDetail(testContext.getFailedConfigurations());
resultDetail(testContext.getFailedTests());
resultDetail(testContext.getSkippedConfigurations());
resultDetail(testContext.getSkippedTests());
resultDetail(testContext.getPassedTests());
}
}
}
private void resultSummary(
ISuite suite, IResultMap tests, String testname, String style, String details) {
if (!tests.getAllResults().isEmpty()) {
StringBuilder buff = new StringBuilder();
String lastClassName = "";
int mq = 0;
int cq = 0;
for (ITestNGMethod method : getMethodSet(tests, suite)) {
m_row += 1;
m_methodIndex += 1;
ITestClass testClass = method.getTestClass();
String className = testClass.getName();
if (mq == 0) {
String id = (m_testIndex == null ? null : "t" + Integer.toString(m_testIndex));
titleRow(testname + " — " + style + details, 5, id);
m_testIndex = null;
}
if (!className.equalsIgnoreCase(lastClassName)) {
if (mq > 0) {
cq += 1;
m_out.print("" + " 1) {
m_out.print(" rowspan=\"" + mq + "\"");
}
m_out.println(">" + lastClassName + " " + buff);
}
mq = 0;
buff.setLength(0);
lastClassName = className;
}
Set resultSet = tests.getResults(method);
long end = Long.MIN_VALUE;
long start = Long.MAX_VALUE;
for (ITestResult testResult : tests.getResults(method)) {
if (testResult.getEndMillis() > end) {
end = testResult.getEndMillis();
}
if (testResult.getStartMillis() < start) {
start = testResult.getStartMillis();
}
}
mq += 1;
if (mq > 1) {
buff.append("");
}
String description = method.getDescription();
String testInstanceName = resultSet.toArray(new ITestResult[] {})[0].getTestName();
buff.append("")
.append(qualifiedName(method))
.append(" ");
if (description != null && !description.isEmpty()) {
buff.append("(\"").append(description).append("\")");
}
buff.append("");
if (testInstanceName != null) {
buff.append("
(").append(testInstanceName).append(")");
}
buff.append(" ")
.append("")
.append(resultSet.size())
.append(" ")
.append("")
.append(start)
.append(" ")
.append("")
.append(end - start)
.append(" ")
.append(" ");
}
if (mq > 0) {
cq++;
m_out.print("" + " 1) {
m_out.print(" rowspan=\"" + mq + "\"");
}
m_out.println(">" + lastClassName + " " + buff);
}
}
}
/** Starts and defines columns result summary table */
private void startResultSummaryTable() {
tableStart("methodOverview", "summary");
m_out.println(
" Class "
+ "Method # of
Scenarios Start Time
(ms) ");
m_row = 0;
}
private String qualifiedName(ITestNGMethod method) {
StringBuilder addon = new StringBuilder();
String[] groups = method.getGroups();
int length = groups.length;
if (length > 0 && !"basic".equalsIgnoreCase(groups[0])) {
addon.append("(");
for (int i = 0; i < length; i++) {
if (i > 0) {
addon.append(", ");
}
addon.append(groups[i]);
}
addon.append(")");
}
return "" + method.getMethodName() + " " + addon;
}
private void resultDetail(IResultMap tests) {
for (ITestResult result : tests.getAllResults()) {
ITestNGMethod method = result.getMethod();
m_methodIndex++;
String cname = method.getTestClass().getName();
m_out.println(
"" + cname + ":" + method.getMethodName() + "
");
generateForResult(result);
m_out.println("");
}
}
private void generateForResult(ITestResult ans) {
Object[] parameters = ans.getParameters();
boolean hasParameters = parameters != null && parameters.length > 0;
if (hasParameters) {
tableStart("result", null);
m_out.print("");
for (int x = 1; x <= parameters.length; x++) {
m_out.print("Parameter #" + x + " ");
}
m_out.println(" ");
m_out.print("");
for (Object p : parameters) {
m_out.println("" + Utils.escapeHtml(Utils.toString(p)) + " ");
}
m_out.println(" ");
}
List msgs = Reporter.getOutput(ans);
boolean hasReporterOutput = !msgs.isEmpty();
Throwable exception = ans.getThrowable();
boolean hasThrowable = exception != null;
if (hasReporterOutput || hasThrowable) {
if (hasParameters) {
m_out.print(" 1) {
m_out.print(" colspan=\"" + parameters.length + "\"");
}
m_out.println(">");
} else {
m_out.println("");
}
if (hasReporterOutput) {
if (hasThrowable) {
m_out.println("Test Messages
");
}
for (String line : msgs) {
m_out.println(line + "
");
}
}
if (hasThrowable) {
boolean wantsMinimalOutput = ans.getStatus() == ITestResult.SUCCESS;
if (hasReporterOutput) {
m_out.println("" + (wantsMinimalOutput ? "Expected Exception" : "Failure") + "
");
}
generateExceptionReport(exception);
}
if (hasParameters) {
m_out.println(" ");
} else {
m_out.println("");
}
}
if (hasParameters) {
m_out.println("");
}
}
protected void generateExceptionReport(Throwable exception) {
m_out.print("");
m_out.print(Utils.shortStackTrace(exception, true));
m_out.println("");
}
/**
* Since the methods will be sorted chronologically, we want to return the ITestNGMethod from the
* invoked methods.
*/
private Collection getMethodSet(IResultMap tests, ISuite suite) {
List r = Lists.newArrayList();
List invokedMethods = suite.getAllInvokedMethods();
for (IInvokedMethod im : invokedMethods) {
if (tests.getAllMethods().contains(im.getTestMethod())) {
r.add(im);
}
}
Arrays.sort(r.toArray(new IInvokedMethod[r.size()]), new TestSorter());
List result = Lists.newArrayList();
// Add all the invoked methods
for (IInvokedMethod m : r) {
result.add(m.getTestMethod());
}
// Add all the methods that weren't invoked (e.g. skipped) that we
// haven't added yet
for (ITestNGMethod m : tests.getAllMethods()) {
if (!result.contains(m)) {
result.add(m);
}
}
return result;
}
public void generateSuiteSummaryReport(List suites) {
tableStart("testOverview", null);
m_out.print("");
tableColumnStart("Test");
tableColumnStart("Methods
Passed");
tableColumnStart("Scenarios
Passed");
tableColumnStart("# skipped");
tableColumnStart("# failed");
tableColumnStart("Total
Time");
tableColumnStart("Included
Groups");
tableColumnStart("Excluded
Groups");
m_out.println(" ");
NumberFormat formatter = new DecimalFormat("#,##0.0");
int qty_tests = 0;
int qty_pass_m = 0;
int qty_pass_s = 0;
int qty_skip = 0;
int qty_fail = 0;
long time_start = Long.MAX_VALUE;
long time_end = Long.MIN_VALUE;
m_testIndex = 1;
for (ISuite suite : suites) {
if (suites.size() > 1) {
titleRow(suite.getName(), 8);
}
Map tests = suite.getResults();
for (ISuiteResult r : tests.values()) {
qty_tests += 1;
ITestContext overview = r.getTestContext();
startSummaryRow(overview.getName());
int q = getMethodSet(overview.getPassedTests(), suite).size();
qty_pass_m += q;
summaryCell(q, Integer.MAX_VALUE);
q = overview.getPassedTests().size();
qty_pass_s += q;
summaryCell(q, Integer.MAX_VALUE);
q = getMethodSet(overview.getSkippedTests(), suite).size();
qty_skip += q;
summaryCell(q, 0);
q = getMethodSet(overview.getFailedTests(), suite).size();
qty_fail += q;
summaryCell(q, 0);
time_start = Math.min(overview.getStartDate().getTime(), time_start);
time_end = Math.max(overview.getEndDate().getTime(), time_end);
summaryCell(
formatter.format(
(overview.getEndDate().getTime() - overview.getStartDate().getTime()) / 1000.)
+ " seconds",
true);
summaryCell(overview.getIncludedGroups());
summaryCell(overview.getExcludedGroups());
m_out.println(" ");
m_testIndex++;
}
}
if (qty_tests > 1) {
m_out.println("Total ");
summaryCell(qty_pass_m, Integer.MAX_VALUE);
summaryCell(qty_pass_s, Integer.MAX_VALUE);
summaryCell(qty_skip, 0);
summaryCell(qty_fail, 0);
summaryCell(formatter.format((time_end - time_start) / 1000.) + " seconds", true);
m_out.println(" ");
}
m_out.println("");
}
private void summaryCell(String[] val) {
StringBuilder b = new StringBuilder();
for (String v : val) {
b.append(v).append(" ");
}
summaryCell(b.toString(), true);
}
private void summaryCell(String v, boolean isGood) {
m_out.print("" + v + " ");
}
private void startSummaryRow(String label) {
m_row++;
m_out.print(
""
+ label
+ ""
+ " ");
}
private void summaryCell(int v, int maxexpected) {
summaryCell(String.valueOf(v), v <= maxexpected);
}
private void tableStart(String cssclass, String id) {
m_out.println(
"");
m_row = 0;
}
private void tableColumnStart(String label) {
m_out.print("" + label + " ");
}
private void titleRow(String label, int cq) {
titleRow(label, cq, null);
}
private void titleRow(String label, int cq, String id) {
m_out.print("" + label + " ");
m_row = 0;
}
/** Starts HTML stream */
protected void startHtml(PrintWriter out) {
out.println(
"");
out.println("");
out.println("");
out.println("");
out.println("TestNG Report ");
out.println("");
out.println("");
out.println("");
}
/** Finishes HTML stream */
protected void endHtml(PrintWriter out) {
out.println("");
}
// ~ Inner Classes --------------------------------------------------------
/** Arranges methods by classname and method name */
private static final class TestSorter implements Comparator {
// ~ Methods -------------------------------------------------------------
/** Arranges methods by classname and method name */
@Override
public int compare(IInvokedMethod o1, IInvokedMethod o2) {
return (int) (o1.getDate() - o2.getDate());
}
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy