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
A testing framework for the JVM
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";
private static final String JVM_ARG = "emailable.report.name";
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 = System.getProperty(JVM_ARG);
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());
}
}
}
/**
* @param tests
*/
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, method);
m_out.println("");
}
}
private void generateForResult(ITestResult ans, ITestNGMethod method) {
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,method);
}
if (hasParameters) {
m_out.println(" ");
}
else {
m_out.println("");
}
}
if (hasParameters) {
m_out.println("");
}
}
protected void generateExceptionReport(Throwable exception, ITestNGMethod method) {
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