diff --git a/src/main/java/org/testng/internal/Utils.java b/src/main/java/org/testng/internal/Utils.java index bd97baf8dd..741a812ff4 100644 --- a/src/main/java/org/testng/internal/Utils.java +++ b/src/main/java/org/testng/internal/Utils.java @@ -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 null, 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. @@ -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()); @@ -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 null, 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); } diff --git a/src/main/java/org/testng/reporters/SuiteHTMLReporter.java b/src/main/java/org/testng/reporters/SuiteHTMLReporter.java index 3c75de06ac..fff8ddffaa 100755 --- a/src/main/java/org/testng/reporters/SuiteHTMLReporter.java +++ b/src/main/java/org/testng/reporters/SuiteHTMLReporter.java @@ -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; @@ -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("

Methods run, sorted chronologically

"); - sb.append("

" + BEFORE + " means before, " + AFTER + " means after

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

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

\n"); - Utils.writeFile(getOutputDirectory(xmlSuite), outputFileName, sb.toString()); - sb = null; //not needed anymore - - 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"); - StringBuffer table = new StringBuffer(); - boolean addedHeader = false; - for (IInvokedMethod iim : invokedMethods) { - ITestNGMethod tm = iim.getTestMethod(); - table.setLength(0); - if (!addedHeader) { - table.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; - - StringBuffer instances = new StringBuffer(); - for (long o : tm.getInstanceHashCodes()) { - instances.append(o).append(" "); + try (BufferedWriter bw = Utils.openWriter(getOutputDirectory(xmlSuite), outputFileName)) { + bw.append("

Methods run, sorted chronologically

"); + bw.append("

" + BEFORE + " means before, " + AFTER + " 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); } - 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("

TimeDelta (ms)Suite
configuration
Test
configuration
Class
configuration
Groups
configuration
Method
configuration
Test
method
ThreadInstances
\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; + + 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("") + .append(" ") + .append(" ") + .append(td(configurationSuiteMethod)) + .append(td(configurationTestMethod)) + .append(td(configurationClassMethod)) + .append(td(configurationGroupsMethod)) + .append(td(setUpOrTearDownMethod)) + .append(td(testMethod)) + .append(" ") + .append(" ") + .append("\n") + ; } - String date = format.format(iim.getDate()); - table.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") - ; - Utils.appendToFile(getOutputDirectory(xmlSuite), outputFileName, table.toString()); + 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("
").append(date).append("").append(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()); } - Utils.appendToFile(getOutputDirectory(xmlSuite), outputFileName, "\n"); } /**