EmailableReporter2.java revision bbc3d5ac4c477fcc63abb1604206348c4fe13470
1dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linpackage org.testng.reporters; 2dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 3dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport java.io.BufferedWriter; 4dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport java.io.File; 5dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport java.io.FileWriter; 6dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport java.io.IOException; 7dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport java.io.PrintWriter; 8dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport java.text.NumberFormat; 9dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport java.util.Collections; 10dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport java.util.Comparator; 11dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport java.util.Iterator; 12dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport java.util.List; 13dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport java.util.Set; 14dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 15dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport org.testng.IReporter; 16dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport org.testng.ISuite; 17dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport org.testng.ISuiteResult; 18dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport org.testng.ITestContext; 19dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport org.testng.ITestResult; 20dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport org.testng.Reporter; 21dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport org.testng.collections.Lists; 22dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport org.testng.internal.Utils; 23dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport org.testng.log4testng.Logger; 24dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linimport org.testng.xml.XmlSuite; 25dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 26dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin/** 27dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Reporter that generates a single-page HTML report of the test results. 28dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * <p> 29dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Based on an earlier implementation by Paul Mendelson. 30dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * </p> 31dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * 32dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @author Abraham Lin 33dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 34dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Linpublic class EmailableReporter2 implements IReporter { 35dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private static final Logger LOG = Logger.getLogger(EmailableReporter.class); 36dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 37dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected PrintWriter writer; 38dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 39dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected List<SuiteResult> suiteResults = Lists.newArrayList(); 40dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 41dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin // Reusable buffer 42dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private StringBuilder buffer = new StringBuilder(); 43dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 44dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin @Override 45dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites, 46dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin String outputDirectory) { 47dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin try { 48dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer = createWriter(outputDirectory); 49dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } catch (IOException e) { 50dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin LOG.error("Unable to create output file", e); 51dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return; 52dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 53dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin for (ISuite suite : suites) { 54dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin suiteResults.add(new SuiteResult(suite)); 55dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 56dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 57dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeDocumentStart(); 58dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeHead(); 59dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeBody(); 60dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeDocumentEnd(); 61dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 62dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.close(); 63dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 64dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 65dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected PrintWriter createWriter(String outdir) throws IOException { 66dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin new File(outdir).mkdirs(); 67dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return new PrintWriter(new BufferedWriter(new FileWriter(new File( 68dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin outdir, "emailable-report.html")))); 69dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 70dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 71dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected void writeDocumentStart() { 72dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\" \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">"); 73dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<html xmlns=\"http://www.w3.org/1999/xhtml\">"); 74dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 75dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 76dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected void writeHead() { 77dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<head>"); 78dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<title>TestNG Report</title>"); 79dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeStylesheet(); 80dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</head>"); 81dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 82dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 83dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected void writeStylesheet() { 84dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<style type=\"text/css\">"); 85dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("table {margin-bottom:10px;border-collapse:collapse;empty-cells:show}"); 86dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("th,td {border:1px solid #009;padding:.25em .5em}"); 87dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("th {vertical-align:bottom}"); 88dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("td {vertical-align:top}"); 89dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("table a {font-weight:bold}"); 90dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(".stripe td {background-color: #E6EBF9}"); 91dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(".num {text-align:right}"); 92dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(".passedodd td {background-color: #3F3}"); 93dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(".passedeven td {background-color: #0A0}"); 94dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(".skippedodd td {background-color: #DDD}"); 95dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(".skippedeven td {background-color: #CCC}"); 96dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(".failedodd td,.attn {background-color: #F33}"); 97dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(".failedeven td,.stripe .attn {background-color: #D00}"); 98dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(".stacktrace {white-space:pre;font-family:monospace}"); 99dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(".totop {font-size:85%;text-align:center;border-bottom:2px solid #000}"); 100dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</style>"); 101dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 102dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 103dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected void writeBody() { 104dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<body>"); 105dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeSuiteSummary(); 106dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeScenarioSummary(); 107dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeScenarioDetails(); 108dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</body>"); 109dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 110dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 111dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected void writeDocumentEnd() { 112dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</html>"); 113dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 114dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 115dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected void writeSuiteSummary() { 116dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin NumberFormat integerFormat = NumberFormat.getIntegerInstance(); 117dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin NumberFormat decimalFormat = NumberFormat.getNumberInstance(); 118dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 119dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int totalPassedTests = 0; 120dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int totalSkippedTests = 0; 121dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int totalFailedTests = 0; 122dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin long totalDuration = 0; 123dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 124dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<table>"); 125dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<tr>"); 126dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<th>Test</th>"); 127dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<th># Passed</th>"); 128dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<th># Skipped</th>"); 129dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<th># Failed</th>"); 130dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<th>Time (ms)</th>"); 131dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<th>Included Groups</th>"); 132dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<th>Excluded Groups</th>"); 133dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</tr>"); 134dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 135dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int testIndex = 0; 136dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin for (SuiteResult suiteResult : suiteResults) { 137dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<tr><th colspan=\"7\">"); 138dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(Utils.escapeHtml(suiteResult.getSuiteName())); 139dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</th></tr>"); 140dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 141dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin for (TestResult testResult : suiteResult.getTestResults()) { 142dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int passedTests = testResult.getPassedTestCount(); 143dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int skippedTests = testResult.getSkippedTestCount(); 144dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int failedTests = testResult.getFailedTestCount(); 145dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin long duration = testResult.getDuration(); 146dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 147dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<tr"); 148dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin if ((testIndex % 2) == 1) { 149dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(" class=\"stripe\""); 150dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 151dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(">"); 152dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 153dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin buffer.setLength(0); 154dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeTableData(buffer.append("<a href=\"#t").append(testIndex) 155dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .append("\">") 156dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .append(Utils.escapeHtml(testResult.getTestName())) 157dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .append("</a>").toString()); 158dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeTableData(integerFormat.format(passedTests), "num"); 159dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeTableData(integerFormat.format(skippedTests), 160dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin (skippedTests > 0 ? "num attn" : "num")); 161dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeTableData(integerFormat.format(failedTests), 162dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin (failedTests > 0 ? "num attn" : "num")); 163dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeTableData(decimalFormat.format(duration), "num"); 164dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeTableData(testResult.getIncludedGroups()); 165dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeTableData(testResult.getExcludedGroups()); 166dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 167dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</tr>"); 168dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 169dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin totalPassedTests += passedTests; 170dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin totalSkippedTests += skippedTests; 171dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin totalFailedTests += failedTests; 172dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin totalDuration += duration; 173dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 174dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin testIndex++; 175dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 176dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 177dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 178dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin // Print totals if there was more than one test 179dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin if (testIndex > 1) { 180dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<tr>"); 181dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<th>Total</th>"); 182dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeTableHeader(integerFormat.format(totalPassedTests), "num"); 183dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeTableHeader(integerFormat.format(totalSkippedTests), 184dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin (totalSkippedTests > 0 ? "num attn" : "num")); 185dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeTableHeader(integerFormat.format(totalFailedTests), 186dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin (totalFailedTests > 0 ? "num attn" : "num")); 187dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeTableHeader(decimalFormat.format(totalDuration), "num"); 188dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<th colspan=\"2\"></th>"); 189dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</tr>"); 190dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 191dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 192dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</table>"); 193dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 194dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 195dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 196dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Writes a summary of all the test scenarios. 197dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 198dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected void writeScenarioSummary() { 199dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<table>"); 200dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<thead>"); 201dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<tr>"); 202dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<th>Class</th>"); 203dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<th>Method</th>"); 204dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<th>Start</th>"); 205dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<th>Time (ms)</th>"); 206dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</tr>"); 207dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</thead>"); 208dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 209dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int testIndex = 0; 210dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int scenarioIndex = 0; 211dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin for (SuiteResult suiteResult : suiteResults) { 212dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<tbody><tr><th colspan=\"4\">"); 213dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(Utils.escapeHtml(suiteResult.getSuiteName())); 214dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</th></tr></tbody>"); 215dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 216dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin for (TestResult testResult : suiteResult.getTestResults()) { 217dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<tbody id=\"t"); 218dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(testIndex); 219dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("\">"); 220dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 221dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin String testName = Utils.escapeHtml(testResult.getTestName()); 222dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 223dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex += writeScenarioSummary(testName 224dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin + " — failed (configuration methods)", 225dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin testResult.getFailedConfigurationResults(), "failed", 226dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex); 227dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex += writeScenarioSummary(testName 228dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin + " — failed", testResult.getFailedTestResults(), 229dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin "failed", scenarioIndex); 230dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex += writeScenarioSummary(testName 231dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin + " — skipped (configuration methods)", 232dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin testResult.getSkippedConfigurationResults(), "skipped", 233dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex); 234dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex += writeScenarioSummary(testName 235dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin + " — skipped", 236dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin testResult.getSkippedTestResults(), "skipped", 237dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex); 238dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex += writeScenarioSummary(testName 239dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin + " — passed", testResult.getPassedTestResults(), 240dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin "passed", scenarioIndex); 241dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 242dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</tbody>"); 243dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 244dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin testIndex++; 245dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 246dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 247dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 248dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</table>"); 249dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 250dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 251dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 252dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Writes the scenario summary for the results of a given state for a single 253dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * test. 254dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 255dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private int writeScenarioSummary(String description, 256dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin List<ClassResult> classResults, String cssClassPrefix, 257dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int startingScenarioIndex) { 258dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int scenarioCount = 0; 259dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin if (!classResults.isEmpty()) { 260dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<tr><th colspan=\"4\">"); 261dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(description); 262dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</th></tr>"); 263dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 264dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int scenarioIndex = startingScenarioIndex; 265dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int classIndex = 0; 266dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin for (ClassResult classResult : classResults) { 267dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin String cssClass = cssClassPrefix 268dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin + ((classIndex % 2) == 0 ? "even" : "odd"); 269dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 270dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin buffer.setLength(0); 271dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 272dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int scenariosPerClass = 0; 273dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int methodIndex = 0; 274dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin for (MethodResult methodResult : classResult.getMethodResults()) { 275dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin List<ITestResult> results = methodResult.getResults(); 276dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int resultsCount = results.size(); 277dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin assert resultsCount > 0; 278dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 279dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin ITestResult firstResult = results.iterator().next(); 280dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin String methodName = Utils.escapeHtml(firstResult 281dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .getMethod().getMethodName()); 282dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin long start = firstResult.getStartMillis(); 283dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin long duration = firstResult.getEndMillis() - start; 284dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 285dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin // The first method per class shares a row with the class 286dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin // header 287dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin if (methodIndex > 0) { 288dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin buffer.append("<tr class=\"").append(cssClass) 289dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .append("\">"); 290dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 291dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 292dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 293dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin // Write the timing information with the first scenario per 294dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin // method 295dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin buffer.append("<td><a href=\"#m").append(scenarioIndex) 296dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .append("\">").append(methodName) 297dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .append("</a></td>").append("<td rowspan=\"") 298dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .append(resultsCount).append("\">").append(start) 299dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .append("</td>").append("<td rowspan=\"") 300dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .append(resultsCount).append("\">") 301dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .append(duration).append("</td></tr>"); 302dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex++; 303dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 304dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin // Write the remaining scenarios for the method 305dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin for (int i = 1; i < resultsCount; i++) { 306dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin buffer.append("<tr class=\"").append(cssClass) 307dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .append("\">").append("<td><a href=\"#m") 308dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .append(scenarioIndex).append("\">") 309dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .append(methodName).append("</a></td></tr>"); 310dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex++; 311dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 312dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 313dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenariosPerClass += resultsCount; 314dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin methodIndex++; 315dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 316dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 317dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin // Write the test results for the class 318dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<tr class=\""); 319dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(cssClass); 320dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("\">"); 321dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<td rowspan=\""); 322dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(scenariosPerClass); 323dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("\">"); 324dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(Utils.escapeHtml(classResult.getClassName())); 325dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</td>"); 326dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(buffer); 327dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 328dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin classIndex++; 329dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 330dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioCount = scenarioIndex - startingScenarioIndex; 331dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 332dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return scenarioCount; 333dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 334dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 335dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 336dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Writes the details for all test scenarios. 337dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 338dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected void writeScenarioDetails() { 339dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int scenarioIndex = 0; 340dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin for (SuiteResult suiteResult : suiteResults) { 341dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin for (TestResult testResult : suiteResult.getTestResults()) { 342dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<h2>"); 343dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(Utils.escapeHtml(testResult.getTestName())); 344dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</h2>"); 345dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 346dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex += writeScenarioDetails( 347dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin testResult.getFailedConfigurationResults(), 348dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex); 349dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex += writeScenarioDetails( 350dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin testResult.getFailedTestResults(), scenarioIndex); 351dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex += writeScenarioDetails( 352dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin testResult.getSkippedConfigurationResults(), 353dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex); 354dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex += writeScenarioDetails( 355dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin testResult.getSkippedTestResults(), scenarioIndex); 356dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex += writeScenarioDetails( 357dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin testResult.getPassedTestResults(), scenarioIndex); 358dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 359dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 360dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 361dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 362dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 363dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Writes the scenario details for the results of a given state for a single 364dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * test. 365dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 366dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private int writeScenarioDetails(List<ClassResult> classResults, 367dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int startingScenarioIndex) { 368dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int scenarioIndex = startingScenarioIndex; 369dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin for (ClassResult classResult : classResults) { 370dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin String className = classResult.getClassName(); 371dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin for (MethodResult methodResult : classResult.getMethodResults()) { 372dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin List<ITestResult> results = methodResult.getResults(); 373dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin assert !results.isEmpty(); 374dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 375dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin String label = Utils 376dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .escapeHtml(className 377dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin + "#" 378dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin + results.iterator().next().getMethod() 379dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .getMethodName()); 380dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin for (ITestResult result : results) { 381dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeScenario(scenarioIndex, label, result); 382dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin scenarioIndex++; 383dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 384dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 385dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 386dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 387dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return scenarioIndex - startingScenarioIndex; 388dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 389dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 390dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 391dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Writes the details for an individual test scenario. 392dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 393dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private void writeScenario(int scenarioIndex, String label, 394dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin ITestResult result) { 395dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<h3 id=\"m"); 396dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(scenarioIndex); 397dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("\">"); 398dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(label); 399dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</h3>"); 400dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 401dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<table class=\"result\">"); 402dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 403dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin // Write test parameters (if any) 404dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin Object[] parameters = result.getParameters(); 405dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int parameterCount = (parameters == null ? 0 : parameters.length); 406dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin if (parameterCount > 0) { 407dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<tr class=\"param\">"); 408dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin for (int i = 1; i <= parameterCount; i++) { 409dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<th>Parameter #"); 410dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(i); 411dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</th>"); 412dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 413dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</tr><tr class=\"param stripe\">"); 414dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin for (Object parameter : parameters) { 415dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<td>"); 416dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(Utils.escapeHtml(Utils.toString(parameter))); 417dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</td>"); 418dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 419dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</tr>"); 420dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 421dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 422dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin // Write reporter messages (if any) 423dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin List<String> reporterMessages = Reporter.getOutput(result); 424dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin if (!reporterMessages.isEmpty()) { 425dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<tr><th"); 426dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin if (parameterCount > 1) { 427dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(" colspan=\""); 428dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(parameterCount); 429dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("\""); 430dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 431dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(">Messages</th></tr>"); 432dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 433dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<tr><td"); 434dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin if (parameterCount > 1) { 435dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(" colspan=\""); 436dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(parameterCount); 437dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("\""); 438dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 439dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(">"); 440dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeReporterMessages(reporterMessages); 441dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</td></tr>"); 442dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 443dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 444dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin // Write exception (if any) 445dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin Throwable throwable = result.getThrowable(); 446dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin if (throwable != null) { 447dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<tr><th"); 448dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin if (parameterCount > 1) { 449dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(" colspan=\""); 450dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(parameterCount); 451dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("\""); 452dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 453dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(">"); 454dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print((result.getStatus() == ITestResult.SUCCESS ? "Expected Exception" 455dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin : "Exception")); 456dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</th></tr>"); 457dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 458dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<tr><td"); 459dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin if (parameterCount > 1) { 460dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(" colspan=\""); 461dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(parameterCount); 462dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("\""); 463dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 464dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(">"); 465dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeStackTrace(throwable); 466dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</td></tr>"); 467dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 468dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 469dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</table>"); 470dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<p class=\"totop\"><a href=\"#summary\">back to summary</a></p>"); 471dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 472dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 473dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected void writeReporterMessages(List<String> reporterMessages) { 474dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<div class=\"messages\">"); 475dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin Iterator<String> iterator = reporterMessages.iterator(); 476dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin assert iterator.hasNext(); 477dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(Utils.escapeHtml(iterator.next())); 478dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin while (iterator.hasNext()) { 479dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<br/>"); 480dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(Utils.escapeHtml(iterator.next())); 481dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 482dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</div>"); 483dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 484dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 485dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected void writeStackTrace(Throwable throwable) { 486dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<div class=\"stacktrace\">"); 487dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(Utils.stackTrace(throwable, true)[0]); 488dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</div>"); 489dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 490dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 491dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 492dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Writes a TH element with the specified contents and CSS class names. 493dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * 494dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @param html 495dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * the HTML contents 496dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @param cssClasses 497dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * the space-delimited CSS classes or null if there are no 498dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * classes to apply 499dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 500dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected void writeTableHeader(String html, String cssClasses) { 501dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeTag("th", html, cssClasses); 502dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 503dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 504dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 505dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Writes a TD element with the specified contents. 506dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * 507dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @param html 508dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * the HTML contents 509dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 510dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected void writeTableData(String html) { 511dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeTableData(html, null); 512dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 513dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 514dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 515dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Writes a TD element with the specified contents and CSS class names. 516dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * 517dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @param html 518dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * the HTML contents 519dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @param cssClasses 520dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * the space-delimited CSS classes or null if there are no 521dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * classes to apply 522dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 523dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected void writeTableData(String html, String cssClasses) { 524dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writeTag("td", html, cssClasses); 525dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 526dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 527dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 528dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Writes an arbitrary HTML element with the specified contents and CSS 529dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * class names. 530dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * 531dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @param tag 532dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * the tag name 533dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @param html 534dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * the HTML contents 535dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @param cssClasses 536dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * the space-delimited CSS classes or null if there are no 537dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * classes to apply 538dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 539dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected void writeTag(String tag, String html, String cssClasses) { 540dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("<"); 541dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(tag); 542dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin if (cssClasses != null) { 543dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(" class=\""); 544dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(cssClasses); 545dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("\""); 546dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 547dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(">"); 548dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(html); 549dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print("</"); 550dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(tag); 551dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin writer.print(">"); 552dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 553dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 554dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 555dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Groups {@link TestResult}s by suite. 556dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 557dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected static class SuiteResult { 558dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private final String suiteName; 559dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private final List<TestResult> testResults = Lists.newArrayList(); 560dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 561dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public SuiteResult(ISuite suite) { 562dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin suiteName = suite.getName(); 563dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin for (ISuiteResult suiteResult : suite.getResults().values()) { 564dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin testResults.add(new TestResult(suiteResult.getTestContext())); 565dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 566dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 567dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 568dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public String getSuiteName() { 569dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return suiteName; 570dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 571dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 572dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 573dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @return the test results (possibly empty) 574dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 575dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public List<TestResult> getTestResults() { 576dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return testResults; 577dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 578dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 579dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 580dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 581dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Groups {@link ClassResult}s by test, type (configuration or test), and 582dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * status. 583dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 584dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected static class TestResult { 585dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 586dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Orders test results by class name and then by method name (in 587dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * lexicographic order). 588dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 589dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected static final Comparator<ITestResult> RESULT_COMPARATOR = new Comparator<ITestResult>() { 590dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin @Override 591dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public int compare(ITestResult o1, ITestResult o2) { 592dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin int result = o1.getTestClass().getName() 593dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .compareTo(o2.getTestClass().getName()); 594dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin if (result == 0) { 595dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin result = o1.getMethod().getMethodName() 596dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .compareTo(o2.getMethod().getMethodName()); 597dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 598dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return result; 599dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 600dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin }; 601dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 602dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private final String testName; 603dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private final List<ClassResult> failedConfigurationResults; 604dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private final List<ClassResult> failedTestResults; 605dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private final List<ClassResult> skippedConfigurationResults; 606dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private final List<ClassResult> skippedTestResults; 607dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private final List<ClassResult> passedTestResults; 608dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private final int failedTestCount; 609dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private final int skippedTestCount; 610dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private final int passedTestCount; 611dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private final long duration; 612dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private final String includedGroups; 613dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private final String excludedGroups; 614dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 615dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public TestResult(ITestContext context) { 616dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin testName = context.getName(); 617dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 618dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin Set<ITestResult> failedConfigurations = context 619dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .getFailedConfigurations().getAllResults(); 620dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin Set<ITestResult> failedTests = context.getFailedTests() 621dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .getAllResults(); 622dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin Set<ITestResult> skippedConfigurations = context 623dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .getSkippedConfigurations().getAllResults(); 624dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin Set<ITestResult> skippedTests = context.getSkippedTests() 625dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .getAllResults(); 626dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin Set<ITestResult> passedTests = context.getPassedTests() 627dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin .getAllResults(); 628dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 629dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin failedConfigurationResults = groupResults(failedConfigurations); 630dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin failedTestResults = groupResults(failedTests); 631dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin skippedConfigurationResults = groupResults(skippedConfigurations); 632dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin skippedTestResults = groupResults(skippedTests); 633dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin passedTestResults = groupResults(passedTests); 634dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 635dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin failedTestCount = failedTests.size(); 636dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin skippedTestCount = skippedTests.size(); 637dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin passedTestCount = passedTests.size(); 638dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 639dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin duration = context.getEndDate().getTime() 640dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin - context.getStartDate().getTime(); 641dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 642dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin includedGroups = formatGroups(context.getIncludedGroups()); 643dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin excludedGroups = formatGroups(context.getExcludedGroups()); 644dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 645dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 646dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 647dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Groups test results by method and then by class. 648dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 649dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected List<ClassResult> groupResults(Set<ITestResult> results) { 650dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin List<ClassResult> classResults = Lists.newArrayList(); 651dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin if (!results.isEmpty()) { 652dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin List<MethodResult> resultsPerClass = Lists.newArrayList(); 653dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin List<ITestResult> resultsPerMethod = Lists.newArrayList(); 654dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 655dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin List<ITestResult> resultsList = Lists.newArrayList(results); 656dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin Collections.sort(resultsList, RESULT_COMPARATOR); 657dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin Iterator<ITestResult> resultsIterator = resultsList.iterator(); 658dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin assert resultsIterator.hasNext(); 659dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 660dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin ITestResult result = resultsIterator.next(); 661dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin resultsPerMethod.add(result); 662dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 663dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin String previousClassName = result.getTestClass().getName(); 664dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin String previousMethodName = result.getMethod().getMethodName(); 665dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin while (resultsIterator.hasNext()) { 666dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin result = resultsIterator.next(); 667dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 668bbc3d5ac4c477fcc63abb1604206348c4fe13470Abraham Lin String className = result.getTestClass().getName(); 669bbc3d5ac4c477fcc63abb1604206348c4fe13470Abraham Lin if (!previousClassName.equals(className)) { 670bbc3d5ac4c477fcc63abb1604206348c4fe13470Abraham Lin // Different class implies different method 671dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin assert !resultsPerMethod.isEmpty(); 672dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin resultsPerClass.add(new MethodResult(resultsPerMethod)); 673dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin resultsPerMethod = Lists.newArrayList(); 674dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 675dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin assert !resultsPerClass.isEmpty(); 676dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin classResults.add(new ClassResult(previousClassName, 677dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin resultsPerClass)); 678dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin resultsPerClass = Lists.newArrayList(); 679dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 680dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin previousClassName = className; 681bbc3d5ac4c477fcc63abb1604206348c4fe13470Abraham Lin previousMethodName = result.getMethod().getMethodName(); 682bbc3d5ac4c477fcc63abb1604206348c4fe13470Abraham Lin } else { 683bbc3d5ac4c477fcc63abb1604206348c4fe13470Abraham Lin String methodName = result.getMethod().getMethodName(); 684bbc3d5ac4c477fcc63abb1604206348c4fe13470Abraham Lin if (!previousMethodName.equals(methodName)) { 685bbc3d5ac4c477fcc63abb1604206348c4fe13470Abraham Lin assert !resultsPerMethod.isEmpty(); 686bbc3d5ac4c477fcc63abb1604206348c4fe13470Abraham Lin resultsPerClass.add(new MethodResult(resultsPerMethod)); 687bbc3d5ac4c477fcc63abb1604206348c4fe13470Abraham Lin resultsPerMethod = Lists.newArrayList(); 688bbc3d5ac4c477fcc63abb1604206348c4fe13470Abraham Lin 689bbc3d5ac4c477fcc63abb1604206348c4fe13470Abraham Lin previousMethodName = methodName; 690bbc3d5ac4c477fcc63abb1604206348c4fe13470Abraham Lin } 691dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 692bbc3d5ac4c477fcc63abb1604206348c4fe13470Abraham Lin resultsPerMethod.add(result); 693dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 694dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin assert !resultsPerMethod.isEmpty(); 695dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin resultsPerClass.add(new MethodResult(resultsPerMethod)); 696dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin assert !resultsPerClass.isEmpty(); 697dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin classResults.add(new ClassResult(previousClassName, 698dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin resultsPerClass)); 699dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 700dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return classResults; 701dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 702dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 703dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public String getTestName() { 704dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return testName; 705dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 706dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 707dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 708dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @return the results for failed configurations (possibly empty) 709dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 710dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public List<ClassResult> getFailedConfigurationResults() { 711dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return failedConfigurationResults; 712dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 713dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 714dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 715dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @return the results for failed tests (possibly empty) 716dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 717dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public List<ClassResult> getFailedTestResults() { 718dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return failedTestResults; 719dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 720dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 721dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 722dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @return the results for skipped configurations (possibly empty) 723dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 724dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public List<ClassResult> getSkippedConfigurationResults() { 725dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return skippedConfigurationResults; 726dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 727dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 728dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 729dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @return the results for skipped tests (possibly empty) 730dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 731dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public List<ClassResult> getSkippedTestResults() { 732dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return skippedTestResults; 733dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 734dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 735dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 736dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @return the results for passed tests (possibly empty) 737dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 738dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public List<ClassResult> getPassedTestResults() { 739dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return passedTestResults; 740dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 741dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 742dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public int getFailedTestCount() { 743dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return failedTestCount; 744dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 745dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 746dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public int getSkippedTestCount() { 747dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return skippedTestCount; 748dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 749dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 750dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public int getPassedTestCount() { 751dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return passedTestCount; 752dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 753dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 754dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public long getDuration() { 755dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return duration; 756dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 757dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 758dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public String getIncludedGroups() { 759dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return includedGroups; 760dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 761dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 762dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public String getExcludedGroups() { 763dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return excludedGroups; 764dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 765dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 766dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 767dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Formats an array of groups for display. 768dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 769dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected String formatGroups(String[] groups) { 770dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin if (groups.length == 0) { 771dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return ""; 772dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 773dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 774dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin StringBuilder builder = new StringBuilder(); 775dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin builder.append(groups[0]); 776dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin for (int i = 1; i < groups.length; i++) { 777dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin builder.append(", ").append(groups[i]); 778dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 779dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return builder.toString(); 780dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 781dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 782dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 783dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 784dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Groups {@link MethodResult}s by class. 785dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 786dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected static class ClassResult { 787dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private final String className; 788dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private final List<MethodResult> methodResults; 789dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 790dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 791dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @param className 792dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * the class name 793dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @param methodResults 794dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * the non-null, non-empty {@link MethodResult} list 795dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 796dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public ClassResult(String className, List<MethodResult> methodResults) { 797dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin this.className = className; 798dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin this.methodResults = methodResults; 799dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 800dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 801dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public String getClassName() { 802dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return className; 803dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 804dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 805dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 806dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @return the non-null, non-empty {@link MethodResult} list 807dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 808dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public List<MethodResult> getMethodResults() { 809dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return methodResults; 810dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 811dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 812dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 813dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 814dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * Groups test results by method. 815dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 816dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin protected static class MethodResult { 817dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin private final List<ITestResult> results; 818dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 819dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 820dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @param results 821dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * the non-null, non-empty result list 822dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 823dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public MethodResult(List<ITestResult> results) { 824dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin this.results = results; 825dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 826dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin 827dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin /** 828dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin * @return the non-null, non-empty result list 829dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin */ 830dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin public List<ITestResult> getResults() { 831dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin return results; 832dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 833dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin } 834dc41cff2ca2b554c5084fe0edc3b40b7eb722b9cAbraham Lin} 835