All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.testng.reporters.SuiteHTMLReporter Maven / Gradle / Ivy

There is a newer version: 7.10.1
Show newest version
package org.testng.reporters;

import static org.testng.internal.Utils.isStringNotEmpty;

import org.testng.IInvokedMethod;
import org.testng.IReporter;
import org.testng.ISuite;
import org.testng.ISuiteResult;
import org.testng.ITestClass;
import org.testng.ITestContext;
import org.testng.ITestNGMethod;
import org.testng.Reporter;
import org.testng.collections.Maps;
import org.testng.internal.ConstructorOrMethod;
import org.testng.internal.Utils;
import org.testng.xml.XmlSuite;

import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;

/**
 * This class implements an HTML reporter for suites.
 *
 * @author cbeust
 * @author Alexandru Popescu
 */
public class SuiteHTMLReporter implements IReporter {
  public static final String METHODS_CHRONOLOGICAL = "methods.html";
  public static final String METHODS_ALPHABETICAL = "methods-alphabetical.html";
  public static final String GROUPS = "groups.html";
  public static final String CLASSES = "classes.html";
  public static final String REPORTER_OUTPUT = "reporter-output.html";
  public static final String METHODS_NOT_RUN = "methods-not-run.html";
  public static final String TESTNG_XML = "testng.xml.html";
  private static final String TD_A_TARGET_MAIN_FRAME_HREF = "").append(title).append("

\n") .append("") .append("\n"); int totalFailedTests = 0; int totalPassedTests = 0; int totalSkippedTests = 0; StringBuilder suiteBuf= new StringBuilder(); for (ISuite suite : suites) { if (suite.getResults().size() == 0) { continue; } String name = suite.getName(); int failedTests= 0; int passedTests= 0; int skippedTests= 0; Map results = suite.getResults(); for (ISuiteResult result : results.values()) { ITestContext context = result.getTestContext(); failedTests += context.getFailedTests().size(); totalFailedTests += context.getFailedTests().size(); passedTests += context.getPassedTests().size(); totalPassedTests += context.getPassedTests().size(); skippedTests += context.getSkippedTests().size(); totalSkippedTests += context.getSkippedTests().size(); } String cls = failedTests > 0 ? "invocation-failed" : (passedTests > 0 ? "invocation-passed" : "invocation-failed"); suiteBuf.append("") .append("\n"); suiteBuf.append("") .append(""); } String cls= totalFailedTests > 0 ? "invocation-failed" : (totalPassedTests > 0 ? "invocation-passed" : "invocation-failed"); sb.append("") .append("") .append("") .append("") .append("") .append("") .append("\n"); sb.append(suiteBuf); sb.append("
SuitePassedFailedSkippedtestng.xml
") .append(name).append("").append(passedTests).append(CLOSE_TD) .append("").append(failedTests).append(CLOSE_TD) .append("").append(skippedTests).append(CLOSE_TD) .append("Link").append("
Total").append(totalPassedTests).append("").append(totalFailedTests).append("").append(totalSkippedTests).append(" 
").append("\n"); Utils.writeFile(m_outputDirectory, "index.html", sb.toString()); } private void generateExcludedMethodsReport(XmlSuite xmlSuite, ISuite suite) { Collection excluded = suite.getExcludedMethods(); StringBuilder sb2 = new StringBuilder("

Methods that were not run

\n"); for (ITestNGMethod method : excluded) { ConstructorOrMethod m = method.getConstructorOrMethod(); if (m != null) { sb2.append("\n"); } } sb2.append("
") .append(m.getDeclaringClass().getName()).append(".").append(m.getName()); String description = method.getDescription(); if(isStringNotEmpty(description)) { sb2.append("
").append(SP2).append("").append(description).append(""); } sb2.append("
"); Utils.writeFile(getOutputDirectory(xmlSuite), METHODS_NOT_RUN, sb2.toString()); } private void generateReporterOutput(XmlSuite xmlSuite) { StringBuilder sb = new StringBuilder(); // // Reporter output // sb.append("

Reporter output

") .append(""); List output = Reporter.getOutput(); for (String line : output) { sb.append("\n"); } sb.append("
").append(line).append("
"); Utils.writeFile(getOutputDirectory(xmlSuite), REPORTER_OUTPUT, sb.toString()); } private void generateClasses(XmlSuite xmlSuite) { StringBuilder sb = new StringBuilder(); sb.append("\n") .append("\n") .append("\n") .append("\n") .append("\n") .append("") ; for (ITestClass tc : m_classes.values()) { sb.append(generateClass(tc)); } sb.append("
Class nameMethod nameGroups
\n"); Utils.writeFile(getOutputDirectory(xmlSuite), CLASSES, sb.toString()); } private final static String SP = " "; private final static String SP2 = SP + SP + SP + SP; private String generateClass(ITestClass cls) { StringBuilder sb = new StringBuilder(); sb.append("\n") .append("").append(cls.getRealClass().getName()).append("\n") .append(" ") .append(" ") .append("\n") ; String[] tags = new String[] { "@Test", "@BeforeClass", "@BeforeMethod", "@AfterMethod", "@AfterClass" }; ITestNGMethod[][] methods = new ITestNGMethod[][] { cls.getTestMethods(), cls.getBeforeClassMethods(), cls.getBeforeTestMethods(), cls.getAfterTestMethods(), cls.getAfterClassMethods() }; for (int i = 0; i < tags.length; i++) { sb.append("\n") .append("").append(tags[i]).append("\n") .append("\n") .append(dumpMethods(methods[i])) ; } return sb.toString(); } private String dumpMethods(ITestNGMethod[] testMethods) { StringBuilder sb = new StringBuilder(); if(null == testMethods || testMethods.length == 0) { return ""; } for (ITestNGMethod m : testMethods) { sb.append("\n"); sb.append(" \n") .append("").append(m.getMethodName()).append("\n") ; String[] groups = m.getGroups(); if (groups != null && groups.length > 0) { sb.append(""); for (String g : groups) { sb.append(g).append(" "); } sb.append("\n"); } else { sb.append(" "); } sb.append("\n"); } return sb.toString(); } /** * Generate information about the methods that were run */ public static final String AFTER= "<<"; public static final String BEFORE = ">>"; private void generateMethodsChronologically(XmlSuite xmlSuite, ISuite suite, String outputFileName, boolean alphabetical) { try (BufferedWriter bw = Utils.openWriter(getOutputDirectory(xmlSuite), outputFileName)) { bw.append("

Methods run, sorted chronologically

"); bw.append("

").append(BEFORE).append(" means before, ").append(AFTER).append(" means after

"); long startDate = -1; bw.append("
").append(suite.getName()).append("

"); bw.append("(Hover the method name to see the test class name)

\n"); Collection invokedMethods = suite.getAllInvokedMethods(); if (alphabetical) { @SuppressWarnings({"unchecked"}) Comparator alphabeticalComparator = new Comparator(){ @Override public int compare(Object o1, Object o2) { IInvokedMethod m1 = (IInvokedMethod) o1; IInvokedMethod m2 = (IInvokedMethod) o2; return m1.getTestMethod().getMethodName().compareTo(m2.getTestMethod().getMethodName()); } }; Collections.sort((List) invokedMethods, alphabeticalComparator); } SimpleDateFormat format = new SimpleDateFormat("yy/MM/dd HH:mm:ss"); boolean addedHeader = false; for (IInvokedMethod iim : invokedMethods) { ITestNGMethod tm = iim.getTestMethod(); if (!addedHeader) { bw.append("

\n") .append("") .append("") .append("") .append("") .append("") .append("") .append("") .append("") .append("") .append("") .append("") .append("\n"); addedHeader = true; } String methodName = tm.toString(); boolean bc = tm.isBeforeClassConfiguration(); boolean ac = tm.isAfterClassConfiguration(); boolean bt = tm.isBeforeTestConfiguration(); boolean at = tm.isAfterTestConfiguration(); boolean bs = tm.isBeforeSuiteConfiguration(); boolean as = tm.isAfterSuiteConfiguration(); boolean bg = tm.isBeforeGroupsConfiguration(); boolean ag = tm.isAfterGroupsConfiguration(); boolean setUp = tm.isBeforeMethodConfiguration(); boolean tearDown = tm.isAfterMethodConfiguration(); boolean isClassConfiguration = bc || ac; boolean isGroupsConfiguration = bg || ag; boolean isTestConfiguration = bt || at; boolean isSuiteConfiguration = bs || as; boolean isSetupOrTearDown = setUp || tearDown; String configurationClassMethod = isClassConfiguration ? (bc ? BEFORE : AFTER) + methodName : SP; String configurationTestMethod = isTestConfiguration ? (bt ? BEFORE : AFTER) + methodName : SP; String configurationGroupsMethod = isGroupsConfiguration ? (bg ? BEFORE : AFTER) + methodName : SP; String configurationSuiteMethod = isSuiteConfiguration ? (bs ? BEFORE : AFTER) + methodName : SP; String setUpOrTearDownMethod = isSetupOrTearDown ? (setUp ? BEFORE : AFTER) + methodName : SP; String testMethod = tm.isTest() ? methodName : SP; StringBuilder instances = new StringBuilder(); for (long o : tm.getInstanceHashCodes()) { instances.append(o).append(" "); } if (startDate == -1) { startDate = iim.getDate(); } String date = format.format(iim.getDate()); bw.append("") .append(" ") .append(" ") .append(td(configurationSuiteMethod)) .append(td(configurationTestMethod)) .append(td(configurationClassMethod)) .append(td(configurationGroupsMethod)) .append(td(setUpOrTearDownMethod)) .append(td(testMethod)) .append(" ") .append(" ") .append("\n") ; } bw.append("
TimeDelta (ms)Suite
configuration
Test
configuration
Class
configuration
Groups
configuration
Method
configuration
Test
method
ThreadInstances
").append(date).append("").append(Long.toString(iim.getDate() - startDate)).append("").append(tm.getId()).append("").append(instances).append("
\n"); } catch (IOException e) { Utils.log("[SuiteHTMLReporter]", 1, "Error writing to " + outputFileName + ": " + e.getMessage()); } } /** * Generate a HTML color based on the class of the method */ private String createColor(ITestNGMethod tm) { // real class can be null if this client is remote (not serializable) long color = tm.getRealClass() != null ? tm.getRealClass().hashCode() & 0xffffff: 0xffffff; long[] rgb = { ((color & 0xff0000) >> 16) & 0xff, ((color & 0x00ff00) >> 8) & 0xff, color & 0xff }; // Not too dark for (int i = 0; i < rgb.length; i++) { if (rgb[i] < 0x60) { rgb[i] += 0x60; } } long adjustedColor = (rgb[0] << 16) | (rgb[1] << 8) | rgb[2]; return Long.toHexString(adjustedColor); } private String td(String s) { StringBuilder result = new StringBuilder(); String prefix = ""; if (s.startsWith(BEFORE)) { prefix = BEFORE; } else if (s.startsWith(AFTER)) { prefix = AFTER; } if (! s.equals(SP)) { result.append(""); int open = s.lastIndexOf("("); int start = s.substring(0, open).lastIndexOf("."); // int end = s.lastIndexOf(")"); if (start >= 0) { result.append(prefix).append(s.substring(start + 1, open)); } else { result.append(prefix).append(s); } result.append(" \n"); } else { result.append("").append(SP).append(CLOSE_TD); } return result.toString(); } /** * Generate information about methods and groups */ private void generateMethodsAndGroups(XmlSuite xmlSuite, ISuite suite) { StringBuilder sb = new StringBuilder(); Map> groups = suite.getMethodsByGroups(); sb.append("

Groups used for this test run

"); if (groups.size() > 0) { sb.append("\n") .append("") .append(""); String[] groupNames = groups.keySet().toArray(new String[groups.size()]); Arrays.sort(groupNames); for (String group : groupNames) { Collection methods = groups.get(group); sb.append("\n"); } sb.append("
Group nameMethods
").append(group).append(CLOSE_TD); StringBuilder methodNames = new StringBuilder(); Map uniqueMethods = Maps.newHashMap(); for (ITestNGMethod tm : methods) { uniqueMethods.put(tm, tm); } for (ITestNGMethod tm : uniqueMethods.values()) { methodNames.append(tm.toString()).append("
"); } sb.append("
").append(methodNames.toString()).append("
\n"); } Utils.writeFile(getOutputDirectory(xmlSuite), GROUPS, sb.toString()); } private void generateIndex(XmlSuite xmlSuite, ISuite sr) { String index = String.format("Results for %s%n", sr.getName()) + "\n" + "\n" + "\n" + "\n" + "\n"; Utils.writeFile(getOutputDirectory(xmlSuite), "index.html", index); } private String makeTitle(ISuite suite) { return "Results for
" + suite.getName() + ""; } private void generateMain(XmlSuite xmlSuite, ISuite sr) { String index = String.format("Results for %s%n", sr.getName()) + "Select a result on the left-hand pane." + "\n"; Utils.writeFile(getOutputDirectory(xmlSuite), "main.html", index); } /** * */ private void generateTableOfContents(XmlSuite xmlSuite, ISuite suite) { StringBuilder tableOfContents = new StringBuilder(); // // Generate methods and groups hyperlinks // Map suiteResults = suite.getResults(); int groupCount = suite.getMethodsByGroups().size(); int methodCount = 0; for (ISuiteResult sr : suiteResults.values()) { ITestNGMethod[] methods = sr.getTestContext().getAllTestMethods(); methodCount += Utils.calculateInvokedMethodCount(methods); // Collect testClasses for (ITestNGMethod tm : methods) { ITestClass tc = tm.getTestClass(); m_classes.put(tc.getRealClass().getName(), tc); } } String name = "Results for " + suite.getName(); tableOfContents .append("\n") .append("\n") .append("").append(name).append("\n") .append(HtmlHelper.getCssString()) .append("\n") ; tableOfContents .append("\n") .append("

").append(makeTitle(suite)).append("

\n") .append("\n") .append("\n") .append("\n") .append("\n") .append("\n") .append("\n") .append("\n") .append(TD_A_TARGET_MAIN_FRAME_HREF).append(GROUPS).append("'>").append(groupCount).append(pluralize(groupCount, " group")).append("\n") .append(TD_A_TARGET_MAIN_FRAME_HREF).append(REPORTER_OUTPUT).append("'>reporter output\n") .append(TD_A_TARGET_MAIN_FRAME_HREF).append(TESTNG_XML).append("'>testng.xml\n") .append("") .append("
") .append(suiteResults.size()).append(" ").append(pluralize(suiteResults.size(), "test")) .append("") .append("") .append(m_classes.size()).append(" ").append(pluralize(m_classes.size(), "class")) .append("") .append("").append(methodCount).append(" ").append(pluralize(methodCount, "method")).append(":
\n") .append("  ").append("chronological
\n") .append("  ").append("alphabetical
\n") .append("  not run (").append(suite.getExcludedMethods().size()).append(")") .append("
"); // // Generate results for individual tests // // Order the results so we can show the failures first, then the skip and // finally the successes Map redResults = Maps.newHashMap(); Map yellowResults = Maps.newHashMap(); Map greenResults = Maps.newHashMap(); for (Map.Entry entry : suiteResults.entrySet()) { String suiteName = entry.getKey(); ISuiteResult sr = entry.getValue(); ITestContext tc = sr.getTestContext(); int failed = tc.getFailedTests().size(); int skipped = tc.getSkippedTests().size(); int passed = tc.getPassedTests().size(); if (failed > 0) { redResults.put(suiteName, sr); } else if (skipped > 0) { yellowResults.put(suiteName, sr); } else if (passed > 0) { greenResults.put(suiteName, sr); } else { redResults.put(suiteName, sr); } } ISuiteResult[][] results = new ISuiteResult[][] { sortResults(redResults.values()), sortResults(yellowResults.values()), sortResults(greenResults.values()) }; String[] colors = {"failed", "skipped", "passed"}; for (int i = 0; i < colors.length; i++) { ISuiteResult[] r = results[i]; for (ISuiteResult sr: r) { String suiteName = sr.getTestContext().getName(); generateSuiteResult(suiteName, sr, colors[i], tableOfContents); } } tableOfContents.append(""); Utils.writeFile(getOutputDirectory(xmlSuite), "toc.html", tableOfContents.toString()); } private String pluralize(int count, String singular) { return count > 1 ? (singular.endsWith("s") ? singular + "es" : singular + "s") : singular; } private String getOutputDirectory(XmlSuite xmlSuite) { File fileResult = new File(m_outputDirectory + File.separatorChar + xmlSuite.getName()).getAbsoluteFile(); if (! fileResult.exists()) { fileResult.mkdirs(); if (! fileResult.exists()) { Utils.log("Reports", 2, "Problem creating output directory " + fileResult.getAbsolutePath()); } } return fileResult.getAbsolutePath(); } private ISuiteResult[] sortResults(Collection r) { ISuiteResult[] result = r.toArray(new ISuiteResult[r.size()]); Arrays.sort(result); return result; } private void generateSuiteResult(String suiteName, ISuiteResult sr, String cssClass, StringBuilder tableOfContents) { ITestContext tc = sr.getTestContext(); int passed = tc.getPassedTests().size(); int failed = tc.getFailedTests().size(); int skipped = tc.getSkippedTests().size(); String baseFile = tc.getName(); tableOfContents .append("\n\n") .append("

\n") ; tableOfContents.append("

\n") .append("") .append("
") .append(suiteName).append(" (").append(passed).append("/").append(failed).append("/").append(skipped).append(")") .append(CLOSE_TD) .append("\n") .append(" Results\n") .append(CLOSE_TD) .append("
\n") .append("
\n"); } /** * Writes a property file for each suite result. * * @param xmlSuite - The {@link XmlSuite} suite. * @param suite - The {@link ISuite} object. */ private void generateSuites(XmlSuite xmlSuite, ISuite suite) { Map suiteResults = suite.getResults(); for (ISuiteResult sr : suiteResults.values()) { ITestContext testContext = sr.getTestContext(); StringBuilder sb = new StringBuilder(); for (ISuiteResult suiteResult : suiteResults.values()) { sb.append(suiteResult.toString()); } Utils.writeFile(getOutputDirectory(xmlSuite), testContext.getName() + ".properties", sb.toString()); } } }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy