Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Speed up suite html reporter #833

Merged
merged 4 commits into from
Oct 24, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 35 additions & 24 deletions src/main/java/org/testng/internal/Utils.java
Original file line number Diff line number Diff line change
Expand Up @@ -149,19 +149,6 @@ public static void writeFile(@Nullable String outputDir, String fileName, String
writeFile(outDir, fileName, sb, null, false /* don't append */);
}

/**
* Appends contents of the string to the specified file. If output directory/file don't
* exist, they are created.
* @param outputDir output directory. If <tt>null</tt>, then current directory is used
* @param fileName file name
* @param sb string to be appended to file
*/
public static void appendToFile(@Nullable String outputDir, String fileName, String sb) {
String outDirPath= outputDir != null ? outputDir : "";
File outDir= new File(outDirPath);
writeFile(outDir, fileName, sb, null, true /* append */);
}

/**
* Writes the content of the sb string to the file named filename in outDir. If
* outDir does not exist, it is created.
Expand Down Expand Up @@ -200,17 +187,7 @@ private static void writeFile(@Nullable File outDir, String fileName, String sb,
private static void writeFile(File outputFile, String sb, @Nullable String encoding, boolean append) {
BufferedWriter fw = null;
try {
if (!outputFile.exists()) {
outputFile.createNewFile();
}
OutputStreamWriter osw= null;
if (null != encoding) {
osw = new OutputStreamWriter(new FileOutputStream(outputFile, append), encoding);
}
else {
osw = new OutputStreamWriter(new FileOutputStream(outputFile, append));
}
fw = new BufferedWriter(osw);
fw = openWriter(outputFile, encoding, append);
fw.write(sb);

Utils.log("", 3, "Creating " + outputFile.getAbsolutePath());
Expand All @@ -236,6 +213,40 @@ private static void writeFile(File outputFile, String sb, @Nullable String encod
}
}

/**
* Open a BufferedWriter for the specified file. If output directory doesn't
* exist, it is created. If the output file exists, it is deleted. The output file is
* created in any case.
* @param outputDir output directory. If <tt>null</tt>, then current directory is used
* @param fileName file name
* @throws IOException if anything goes wrong while creating files.
*/
public static BufferedWriter openWriter(@Nullable String outputDir, String fileName) throws IOException {
String outDirPath= outputDir != null ? outputDir : "";
File outDir= new File(outDirPath);
if (outDir.exists()) {
outDir.mkdirs();
}
fileName = replaceSpecialCharacters(fileName);
File outputFile = new File(outDir, fileName);
outputFile.delete();
return openWriter(outputFile, null, false);
}

private static BufferedWriter openWriter(File outputFile, @Nullable String encoding, boolean append) throws IOException {
if (!outputFile.exists()) {
outputFile.createNewFile();
}
OutputStreamWriter osw= null;
if (null != encoding) {
osw = new OutputStreamWriter(new FileOutputStream(outputFile, append), encoding);
}
else {
osw = new OutputStreamWriter(new FileOutputStream(outputFile, append));
}
return new BufferedWriter(osw);
}

private static void ppp(String s) {
Utils.log("Utils", 0, s);
}
Expand Down
180 changes: 89 additions & 91 deletions src/main/java/org/testng/reporters/SuiteHTMLReporter.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import org.testng.internal.Utils;
import org.testng.xml.XmlSuite;

import java.io.BufferedWriter;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
Expand Down Expand Up @@ -346,101 +347,98 @@ private String dumpGroups(String[] groups) {
private void generateMethodsChronologically(XmlSuite xmlSuite, ISuite suite,
String outputFileName, boolean alphabetical)
{
StringBuffer sb = new StringBuffer();

sb.append("<h2>Methods run, sorted chronologically</h2>");
sb.append("<h3>" + BEFORE + " means before, " + AFTER + " means after</h3><p/>");

long startDate = -1;
sb.append("<br/><em>").append(suite.getName()).append("</em><p/>");
sb.append("<small><i>(Hover the method name to see the test class name)</i></small><p/>\n");
Utils.writeFile(getOutputDirectory(xmlSuite), outputFileName, sb.toString());
sb = null; //not needed anymore

Collection<IInvokedMethod> invokedMethods = suite.getAllInvokedMethods();
if (alphabetical) {
@SuppressWarnings({"unchecked"})
Comparator<? super ITestNGMethod> 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");
StringBuffer table = new StringBuffer();
boolean addedHeader = false;
for (IInvokedMethod iim : invokedMethods) {
ITestNGMethod tm = iim.getTestMethod();
table.setLength(0);
if (!addedHeader) {
table.append("<table border=\"1\">\n")
.append("<tr>")
.append("<th>Time</th>")
.append("<th>Delta (ms)</th>")
.append("<th>Suite<br>configuration</th>")
.append("<th>Test<br>configuration</th>")
.append("<th>Class<br>configuration</th>")
.append("<th>Groups<br>configuration</th>")
.append("<th>Method<br>configuration</th>")
.append("<th>Test<br>method</th>")
.append("<th>Thread</th>")
.append("<th>Instances</th>")
.append("</tr>\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;

StringBuffer instances = new StringBuffer();
for (long o : tm.getInstanceHashCodes()) {
instances.append(o).append(" ");
try (BufferedWriter bw = Utils.openWriter(getOutputDirectory(xmlSuite), outputFileName)) {
bw.append("<h2>Methods run, sorted chronologically</h2>");
bw.append("<h3>" + BEFORE + " means before, " + AFTER + " means after</h3><p/>");

long startDate = -1;
bw.append("<br/><em>").append(suite.getName()).append("</em><p/>");
bw.append("<small><i>(Hover the method name to see the test class name)</i></small><p/>\n");

Collection<IInvokedMethod> invokedMethods = suite.getAllInvokedMethods();
if (alphabetical) {
@SuppressWarnings({"unchecked"})
Comparator<? super ITestNGMethod> 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);
}

if (startDate == -1) {
startDate = iim.getDate();
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("<table border=\"1\">\n")
.append("<tr>")
.append("<th>Time</th>")
.append("<th>Delta (ms)</th>")
.append("<th>Suite<br>configuration</th>")
.append("<th>Test<br>configuration</th>")
.append("<th>Class<br>configuration</th>")
.append("<th>Groups<br>configuration</th>")
.append("<th>Method<br>configuration</th>")
.append("<th>Test<br>method</th>")
.append("<th>Thread</th>")
.append("<th>Instances</th>")
.append("</tr>\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;

StringBuffer instances = new StringBuffer();
for (long o : tm.getInstanceHashCodes()) {
instances.append(o).append(" ");
}

if (startDate == -1) {
startDate = iim.getDate();
}
String date = format.format(iim.getDate());
bw.append("<tr bgcolor=\"" + createColor(tm) + "\">")
.append(" <td>").append(date).append("</td> ")
.append(" <td>").append(Long.toString(iim.getDate() - startDate)).append("</td> ")
.append(td(configurationSuiteMethod))
.append(td(configurationTestMethod))
.append(td(configurationClassMethod))
.append(td(configurationGroupsMethod))
.append(td(setUpOrTearDownMethod))
.append(td(testMethod))
.append(" <td>").append(tm.getId()).append("</td> ")
.append(" <td>").append(instances).append("</td> ")
.append("</tr>\n")
;
}
String date = format.format(iim.getDate());
table.append("<tr bgcolor=\"" + createColor(tm) + "\">")
.append(" <td>").append(date).append("</td> ")
.append(" <td>").append(iim.getDate() - startDate).append("</td> ")
.append(td(configurationSuiteMethod))
.append(td(configurationTestMethod))
.append(td(configurationClassMethod))
.append(td(configurationGroupsMethod))
.append(td(setUpOrTearDownMethod))
.append(td(testMethod))
.append(" <td>").append(tm.getId()).append("</td> ")
.append(" <td>").append(instances).append("</td> ")
.append("</tr>\n")
;
Utils.appendToFile(getOutputDirectory(xmlSuite), outputFileName, table.toString());
bw.append("</table>\n");
} catch (IOException e) {
Utils.log("[SuiteHTMLReporter]", 1, "Error writing to " + outputFileName + ": " + e.getMessage());
}
Utils.appendToFile(getOutputDirectory(xmlSuite), outputFileName, "</table>\n");
}

/**
Expand Down