Source Code Cross Referenced for EmailableReporter.java in  » Testing » testng » org » testng » reporters » Java Source Code / Java DocumentationJava Source Code and Java Documentation

Java Source Code / Java Documentation
1. 6.0 JDK Core
2. 6.0 JDK Modules
3. 6.0 JDK Modules com.sun
4. 6.0 JDK Modules com.sun.java
5. 6.0 JDK Modules sun
6. 6.0 JDK Platform
7. Ajax
8. Apache Harmony Java SE
9. Aspect oriented
10. Authentication Authorization
11. Blogger System
12. Build
13. Byte Code
14. Cache
15. Chart
16. Chat
17. Code Analyzer
18. Collaboration
19. Content Management System
20. Database Client
21. Database DBMS
22. Database JDBC Connection Pool
23. Database ORM
24. Development
25. EJB Server geronimo
26. EJB Server GlassFish
27. EJB Server JBoss 4.2.1
28. EJB Server resin 3.1.5
29. ERP CRM Financial
30. ESB
31. Forum
32. GIS
33. Graphic Library
34. Groupware
35. HTML Parser
36. IDE
37. IDE Eclipse
38. IDE Netbeans
39. Installer
40. Internationalization Localization
41. Inversion of Control
42. Issue Tracking
43. J2EE
44. JBoss
45. JMS
46. JMX
47. Library
48. Mail Clients
49. Net
50. Parser
51. PDF
52. Portal
53. Profiler
54. Project Management
55. Report
56. RSS RDF
57. Rule Engine
58. Science
59. Scripting
60. Search Engine
61. Security
62. Sevlet Container
63. Source Control
64. Swing Library
65. Template Engine
66. Test Coverage
67. Testing
68. UML
69. Web Crawler
70. Web Framework
71. Web Mail
72. Web Server
73. Web Services
74. Web Services apache cxf 2.0.1
75. Web Services AXIS2
76. Wiki Engine
77. Workflow Engines
78. XML
79. XML UI
Java
Java Tutorial
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
Photoshop Tutorials
Maya Tutorials
Flash Tutorials
3ds-Max Tutorials
Illustrator Tutorials
GIMP Tutorials
C# / C Sharp
C# / CSharp Tutorial
C# / CSharp Open Source
ASP.Net
ASP.NET Tutorial
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
Ruby
PHP
Python
Python Tutorial
Python Open Source
SQL Server / T-SQL
SQL Server / T-SQL Tutorial
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Flash / Flex / ActionScript
VBA / Excel / Access / Word
XML
XML Tutorial
Microsoft Office PowerPoint 2007 Tutorial
Microsoft Office Excel 2007 Tutorial
Microsoft Office Word 2007 Tutorial
Java Source Code / Java Documentation » Testing » testng » org.testng.reporters 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


001:        package org.testng.reporters;
002:
003:        import java.io.BufferedWriter;
004:        import java.io.File;
005:        import java.io.FileWriter;
006:        import java.io.IOException;
007:        import java.io.PrintWriter;
008:        import java.text.DecimalFormat;
009:        import java.text.NumberFormat;
010:        import java.util.Collection;
011:        import java.util.Comparator;
012:        import java.util.List;
013:        import java.util.Map;
014:        import java.util.Set;
015:        import java.util.TreeSet;
016:
017:        import org.testng.IReporter;
018:        import org.testng.IResultMap;
019:        import org.testng.ISuite;
020:        import org.testng.ISuiteResult;
021:        import org.testng.ITestContext;
022:        import org.testng.ITestNGMethod;
023:        import org.testng.ITestResult;
024:        import org.testng.Reporter;
025:        import org.testng.log4testng.Logger;
026:        import org.testng.reporters.util.StackTraceTools;
027:        import org.testng.xml.XmlSuite;
028:
029:        /**
030:         * Reported designed to render self-contained HTML top down view of a testing
031:         * suite.
032:         * 
033:         * @author Paul Mendelson
034:         * @since 5.2
035:         * @version $Revision: 347 $
036:         */
037:        public class EmailableReporter implements  IReporter {
038:            private static final Logger L = Logger
039:                    .getLogger(EmailableReporter.class);
040:
041:            // ~ Instance fields ------------------------------------------------------
042:
043:            private PrintWriter m_out;
044:
045:            private int m_row;
046:
047:            private int m_methodIndex;
048:
049:            private int m_rowTotal;
050:
051:            // ~ Methods --------------------------------------------------------------
052:
053:            /** Creates summary of the run */
054:            public void generateReport(List<XmlSuite> xml, List<ISuite> suites,
055:                    String outdir) {
056:                try {
057:                    m_out = createWriter(outdir);
058:                } catch (IOException e) {
059:                    L.error("output file", e);
060:                    return;
061:                }
062:                startHtml(m_out);
063:                generateSuiteSummaryReport(suites);
064:                generateMethodSummaryReport(suites);
065:                generateMethodDetailReport(suites);
066:                endHtml(m_out);
067:                m_out.flush();
068:                m_out.close();
069:            }
070:
071:            protected PrintWriter createWriter(String outdir)
072:                    throws IOException {
073:                return new PrintWriter(new BufferedWriter(new FileWriter(
074:                        new File(outdir, "emailable-report.html"))));
075:            }
076:
077:            /** Creates a table showing the highlights of each test method with links to the method details */
078:            protected void generateMethodSummaryReport(List<ISuite> suites) {
079:                m_methodIndex = 0;
080:                m_out.println("<a id=\"summary\"></a>");
081:                startResultSummaryTable("passed");
082:                for (ISuite suite : suites) {
083:                    if (suites.size() > 1) {
084:                        titleRow(suite.getName(), 4);
085:                    }
086:                    Map<String, ISuiteResult> r = suite.getResults();
087:                    for (ISuiteResult r2 : r.values()) {
088:                        ITestContext test = r2.getTestContext();
089:                        resultSummary(test.getFailedConfigurations(), test
090:                                .getName(), "failed",
091:                                " (configuration methods)");
092:                        resultSummary(test.getFailedTests(), test.getName(),
093:                                "failed", "");
094:                        resultSummary(test.getSkippedConfigurations(), test
095:                                .getName(), "skipped",
096:                                " (configuration methods)");
097:                        resultSummary(test.getSkippedTests(), test.getName(),
098:                                "skipped", "");
099:                        resultSummary(test.getPassedTests(), test.getName(),
100:                                "passed", "");
101:                    }
102:                }
103:                m_out.println("</table>");
104:            }
105:
106:            /** Creates a section showing known results for each method */
107:            protected void generateMethodDetailReport(List<ISuite> suites) {
108:                m_methodIndex = 0;
109:                for (ISuite suite : suites) {
110:                    Map<String, ISuiteResult> r = suite.getResults();
111:                    for (ISuiteResult r2 : r.values()) {
112:                        if (r.values().size() > 0) {
113:                            m_out.println("<h1>"
114:                                    + r2.getTestContext().getName() + "</h1>");
115:                        }
116:                        resultDetail(r2.getTestContext()
117:                                .getFailedConfigurations(), "failed");
118:                        resultDetail(r2.getTestContext().getFailedTests(),
119:                                "failed");
120:                        resultDetail(r2.getTestContext()
121:                                .getSkippedConfigurations(), "skipped");
122:                        resultDetail(r2.getTestContext().getSkippedTests(),
123:                                "skipped");
124:                        resultDetail(r2.getTestContext().getPassedTests(),
125:                                "passed");
126:                    }
127:                }
128:            }
129:
130:            /**
131:             * @param tests
132:             */
133:            private void resultSummary(IResultMap tests, String testname,
134:                    String style, String details) {
135:                if (tests.getAllResults().size() > 0) {
136:                    StringBuffer buff = new StringBuffer();
137:                    String lastc = "";
138:                    int mq = 0;
139:                    int cq = 0;
140:                    for (ITestNGMethod method : getMethodSet(tests)) {
141:                        m_row += 1;
142:                        m_methodIndex += 1;
143:                        String cname = method.getTestClass().getName();
144:                        if (mq == 0) {
145:                            titleRow(testname + " &#8212; " + style + details,
146:                                    4);
147:                        }
148:                        if (!cname.equalsIgnoreCase(lastc)) {
149:                            if (mq > 0) {
150:                                cq += 1;
151:                                m_out.println("<tr class=\"" + style
152:                                        + (cq % 2 == 0 ? "even" : "odd")
153:                                        + "\">" + "<td rowspan=\"" + mq + "\">"
154:                                        + lastc + buff);
155:                            }
156:                            mq = 0;
157:                            buff.setLength(0);
158:                            lastc = cname;
159:                        }
160:                        Set<ITestResult> result_set = tests.getResults(method);
161:                        long end = Long.MIN_VALUE;
162:                        long start = Long.MAX_VALUE;
163:                        for (ITestResult ans : tests.getResults(method)) {
164:                            if (ans.getEndMillis() > end) {
165:                                end = ans.getEndMillis();
166:                            }
167:                            if (ans.getStartMillis() < start) {
168:                                start = ans.getStartMillis();
169:                            }
170:                        }
171:                        mq += 1;
172:                        if (mq > 1) {
173:                            buff.append("<tr class=\"" + style
174:                                    + (cq % 2 == 0 ? "odd" : "even") + "\">");
175:                        }
176:                        buff.append("<td><a href=\"#m" + m_methodIndex + "\">"
177:                                + qualifiedName(method) + "</a></td>"
178:                                + "<td class=\"numi\">" + result_set.size()
179:                                + "</td><td class=\"numi\">" + (end - start)
180:                                + "</td></tr>");
181:                    }
182:                    if (mq > 0) {
183:                        cq += 1;
184:                        m_out.println("<tr class=\"" + style
185:                                + (cq % 2 == 0 ? "even" : "odd") + "\">"
186:                                + "<td rowspan=\"" + mq + "\">" + lastc + buff);
187:                    }
188:                }
189:            }
190:
191:            /** Starts and defines columns result summary table */
192:            private void startResultSummaryTable(String style) {
193:                tableStart(style);
194:                m_out
195:                        .println("<tr><th>Class</th>"
196:                                + "<th>Method</th><th># of<br/>Scenarios</th><th>Time<br/>(Msecs)</th></tr>");
197:                m_row = 0;
198:            }
199:
200:            private String qualifiedName(ITestNGMethod method) {
201:                String addon = "";
202:                if (method.getGroups().length > 0
203:                        && !"basic".equalsIgnoreCase(method.getGroups()[0])) {
204:                    addon = " (" + method.getGroups()[0] + ")";
205:                }
206:                return method.getMethodName() + addon;
207:            }
208:
209:            private void resultDetail(IResultMap tests, final String style) {
210:                if (tests.getAllResults().size() > 0) {
211:                    int row = 0;
212:                    for (ITestNGMethod method : getMethodSet(tests)) {
213:                        row += 1;
214:                        m_methodIndex += 1;
215:                        String cname = method.getTestClass().getName();
216:                        m_out.println("<a id=\"m" + m_methodIndex
217:                                + "\"></a><h2>" + cname + ":"
218:                                + method.getMethodName() + "</h2>");
219:                        int rq = 0;
220:                        Set<ITestResult> resultSet = tests.getResults(method);
221:                        for (ITestResult ans : resultSet) {
222:                            rq += 1;
223:                            Object[] parameters = ans.getParameters();
224:                            boolean hasParameters = parameters != null
225:                                    && parameters.length > 0;
226:                            if (hasParameters) {
227:                                if (rq == 1) {
228:                                    tableStart("param");
229:                                    m_out.print("<tr>");
230:                                    for (int x = 1; x <= parameters.length; x++) {
231:                                        m_out
232:                                                .print("<th style=\"padding-left:1em;padding-right:1em\">Parameter #"
233:                                                        + x + "</th>");
234:                                    }
235:                                    m_out.println("</tr>");
236:                                }
237:                                m_out.print("<tr"
238:                                        + (rq % 2 == 0 ? " class=\"stripe\""
239:                                                : "") + ">");
240:                                for (Object p : parameters) {
241:                                    m_out
242:                                            .println("<td style=\"padding-left:.5em;padding-right:2em\">"
243:                                                    + (p != null ? p.toString()
244:                                                            : "null") + "</td>");
245:                                }
246:                                m_out.println("</tr>");
247:                            }
248:                            List<String> msgs = Reporter.getOutput(ans);
249:                            boolean hasReporterOutput = msgs.size() > 0;
250:                            Throwable exception = ans.getThrowable();
251:                            boolean hasThrowable = exception != null;
252:                            if (hasReporterOutput || hasThrowable) {
253:                                String indent = " style=\"padding-left:3em\"";
254:                                if (hasParameters) {
255:                                    m_out
256:                                            .println("<tr"
257:                                                    + (rq % 2 == 0 ? " class=\"stripe\""
258:                                                            : "") + "><td"
259:                                                    + indent + " colspan=\""
260:                                                    + parameters.length + "\">");
261:                                } else {
262:                                    m_out.println("<div" + indent + ">");
263:                                }
264:                                if (hasReporterOutput) {
265:                                    if (hasThrowable)
266:                                        m_out.println("<h3>Test Messages</h3>");
267:                                    for (String line : msgs) {
268:                                        m_out.println(line + "<br/>");
269:                                    }
270:                                }
271:                                if (hasThrowable) {
272:                                    boolean wantsMinimalOutput = ans
273:                                            .getStatus() == ITestResult.SUCCESS;
274:                                    if (hasReporterOutput)
275:                                        m_out
276:                                                .println("<h3>"
277:                                                        + (wantsMinimalOutput ? "Expected Exception"
278:                                                                : "Failure")
279:                                                        + "</h3>");
280:                                    generateExceptionReport(exception, method);
281:                                }
282:                                if (hasParameters) {
283:                                    m_out.println("</td></tr>");
284:                                } else {
285:                                    m_out.println("</div>");
286:                                }
287:                            }
288:                            if (hasParameters) {
289:                                if (rq == resultSet.size()) {
290:                                    m_out.println("</table>");
291:                                }
292:                            }
293:                        }
294:                        m_out
295:                                .println("<p class=\"totop\"><a href=\"#summary\">back to summary</a></p>");
296:                    }
297:                }
298:            }
299:
300:            protected void generateExceptionReport(Throwable exception,
301:                    ITestNGMethod method) {
302:                generateExceptionReport(exception, method, exception
303:                        .getLocalizedMessage());
304:            }
305:
306:            private void generateExceptionReport(Throwable exception,
307:                    ITestNGMethod method, String title) {
308:                m_out.println("<p>" + escape(title) + "</p>");
309:                StackTraceElement[] s1 = exception.getStackTrace();
310:                Throwable t2 = exception.getCause();
311:                if (t2 == exception) {
312:                    t2 = null;
313:                }
314:                int maxlines = Math.min(100, StackTraceTools.getTestRoot(s1,
315:                        method));
316:                for (int x = 0; x <= maxlines; x++) {
317:                    m_out.println((x > 0 ? "<br/>at " : "")
318:                            + escape(s1[x].toString()));
319:                }
320:                if (maxlines < s1.length) {
321:                    m_out.println("<br/>" + (s1.length - maxlines)
322:                            + " lines not shown");
323:                }
324:                if (t2 != null) {
325:                    generateExceptionReport(t2, method, "Caused by "
326:                            + t2.getLocalizedMessage());
327:                }
328:            }
329:
330:            private static String escape(String string) {
331:                if (null == string)
332:                    return string;
333:                return string.replaceAll("<", "&lt;").replaceAll(">", "&gt;");
334:            }
335:
336:            /**
337:             * @param tests
338:             * @return
339:             */
340:            private Collection<ITestNGMethod> getMethodSet(IResultMap tests) {
341:                Set r = new TreeSet<ITestNGMethod>(
342:                        new TestSorter<ITestNGMethod>());
343:                r.addAll(tests.getAllMethods());
344:                return r;
345:            }
346:
347:            public void generateSuiteSummaryReport(List<ISuite> suites) {
348:                tableStart("param");
349:                m_out.print("<tr><th>Test</th>");
350:                tableColumnStart("Methods<br/>Passed");
351:                tableColumnStart("Scenarios<br/>Passed");
352:                tableColumnStart("# skipped");
353:                tableColumnStart("# failed");
354:                tableColumnStart("Total<br/>Time");
355:                tableColumnStart("Included<br/>Groups");
356:                tableColumnStart("Excluded<br/>Groups");
357:                m_out.println("</tr>");
358:                NumberFormat formatter = new DecimalFormat("#,##0.0");
359:                int qty_tests = 0;
360:                int qty_pass_m = 0;
361:                int qty_pass_s = 0;
362:                int qty_skip = 0;
363:                int qty_fail = 0;
364:                long time_start = Long.MAX_VALUE;
365:                long time_end = Long.MIN_VALUE;
366:                for (ISuite suite : suites) {
367:                    if (suites.size() > 1) {
368:                        titleRow(suite.getName(), 7);
369:                    }
370:                    Map<String, ISuiteResult> tests = suite.getResults();
371:                    for (ISuiteResult r : tests.values()) {
372:                        qty_tests += 1;
373:                        ITestContext overview = r.getTestContext();
374:                        startSummaryRow(overview.getName());
375:                        int q = getMethodSet(overview.getPassedTests()).size();
376:                        qty_pass_m += q;
377:                        summaryCell(q, Integer.MAX_VALUE);
378:                        q = overview.getPassedTests().size();
379:                        qty_pass_s += q;
380:                        summaryCell(q, Integer.MAX_VALUE);
381:                        q = getMethodSet(overview.getSkippedTests()).size();
382:                        qty_skip += q;
383:                        summaryCell(q, 0);
384:                        q = getMethodSet(overview.getFailedTests()).size();
385:                        qty_fail += q;
386:                        summaryCell(q, 0);
387:                        time_start = Math.min(
388:                                overview.getStartDate().getTime(), time_start);
389:                        time_end = Math.max(overview.getEndDate().getTime(),
390:                                time_end);
391:                        summaryCell(
392:                                formatter.format((overview.getEndDate()
393:                                        .getTime() - overview.getStartDate()
394:                                        .getTime()) / 1000.)
395:                                        + " seconds", true);
396:                        summaryCell(overview.getIncludedGroups());
397:                        summaryCell(overview.getExcludedGroups());
398:                        m_out.println("</tr>");
399:                    }
400:                }
401:                if (qty_tests > 1) {
402:                    m_out.println("<tr class=\"total\"><td>Total</td>");
403:                    summaryCell(qty_pass_m, Integer.MAX_VALUE);
404:                    summaryCell(qty_pass_s, Integer.MAX_VALUE);
405:                    summaryCell(qty_skip, 0);
406:                    summaryCell(qty_fail, 0);
407:                    summaryCell(formatter
408:                            .format((time_end - time_start) / 1000.)
409:                            + " seconds", true);
410:                    m_out.println("<td colspan=\"2\">&nbsp;</td></tr>");
411:                }
412:                m_out.println("</table>");
413:            }
414:
415:            private void summaryCell(String[] val) {
416:                StringBuffer b = new StringBuffer();
417:                for (String v : val) {
418:                    b.append(v + " ");
419:                }
420:                summaryCell(b.toString(), true);
421:            }
422:
423:            private void summaryCell(String v, boolean isgood) {
424:                m_out.print("<td class=\"numi" + (isgood ? "" : "_attn")
425:                        + "\">" + v + "</td>");
426:            }
427:
428:            private void startSummaryRow(String label) {
429:                m_row += 1;
430:                m_out.print("<tr" + (m_row % 2 == 0 ? " class=\"stripe\"" : "")
431:                        + "><td style=\"text-align:left;padding-right:2em\">"
432:                        + label + "</td>");
433:            }
434:
435:            private void summaryCell(int v, int maxexpected) {
436:                summaryCell(String.valueOf(v), v <= maxexpected);
437:                m_rowTotal += v;
438:            }
439:
440:            /**
441:             * 
442:             */
443:            private void tableStart(String cssclass) {
444:                m_out.println("<table cellspacing=0 cellpadding=0"
445:                        + (cssclass != null ? " class=\"" + cssclass + "\""
446:                                : " style=\"padding-bottom:2em\"") + ">");
447:                m_row = 0;
448:            }
449:
450:            private void tableColumnStart(String label) {
451:                m_out.print("<th class=\"numi\">" + label + "</th>");
452:            }
453:
454:            private void titleRow(String label, int cq) {
455:                m_out.println("<tr><th colspan=\"" + cq + "\">" + label
456:                        + "</th></tr>");
457:                m_row = 0;
458:            }
459:
460:            protected void writeStyle(String[] formats, String[] targets) {
461:
462:            }
463:
464:            /** Starts HTML stream */
465:            protected void startHtml(PrintWriter out) {
466:                out
467:                        .println("<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">");
468:                out.println("<html xmlns=\"http://www.w3.org/1999/xhtml\">");
469:                out.println("<head>");
470:                out.println("<title>TestNG:  Unit Test</title>");
471:                out.println("<style type=\"text/css\">");
472:                out
473:                        .println("table caption,table.info_table,table.param,table.passed,table.failed {margin-bottom:10px;border:1px solid #000099;border-collapse:collapse;empty-cells:show;}");
474:                out
475:                        .println("table.info_table td,table.info_table th,table.param td,table.param th,table.passed td,table.passed th,table.failed td,table.failed th {");
476:                out
477:                        .println("border:1px solid #000099;padding:.25em .5em .25em .5em");
478:                out.println("}");
479:                out.println("table.param th {vertical-align:bottom}");
480:                out.println("td.numi,th.numi,td.numi_attn {");
481:                out.println("text-align:right");
482:                out.println("}");
483:                out.println("tr.total td {font-weight:bold}");
484:                out.println("table caption {");
485:                out.println("text-align:center;font-weight:bold;");
486:                out.println("}");
487:                out
488:                        .println("table.passed tr.stripe td,table tr.passedodd td {background-color: #00AA00;}");
489:                out
490:                        .println("table.passed td,table tr.passedeven td {background-color: #33FF33;}");
491:                out
492:                        .println("table.passed tr.stripe td,table tr.skippedodd td {background-color: #cccccc;}");
493:                out
494:                        .println("table.passed td,table tr.skippedodd td {background-color: #dddddd;}");
495:                out
496:                        .println("table.failed tr.stripe td,table tr.failedodd td,table.param td.numi_attn {background-color: #FF3333;}");
497:                out
498:                        .println("table.failed td,table tr.failedeven td,table.param tr.stripe td.numi_attn {background-color: #DD0000;}");
499:                out
500:                        .println("tr.stripe td,tr.stripe th {background-color: #E6EBF9;}");
501:                out
502:                        .println("p.totop {font-size:85%;text-align:center;border-bottom:2px black solid}");
503:                out
504:                        .println("div.shootout {padding:2em;border:3px #4854A8 solid}");
505:                out.println("</style>");
506:                out.println("</head>");
507:                out.println("<body>");
508:            }
509:
510:            /** Finishes HTML stream */
511:            protected void endHtml(PrintWriter out) {
512:                out.println("</body></html>");
513:            }
514:
515:            // ~ Inner Classes --------------------------------------------------------
516:            /** Arranges methods by classname and method name */
517:            private class TestSorter<T extends ITestNGMethod> implements 
518:                    Comparator {
519:                // ~ Methods -------------------------------------------------------------
520:
521:                /** Arranges methods by classname and method name */
522:                public int compare(Object o1, Object o2) {
523:                    int r = ((T) o1).getTestClass().getName().compareTo(
524:                            ((T) o2).getTestClass().getName());
525:                    if (r == 0) {
526:                        r = ((T) o1).getMethodName().compareTo(
527:                                ((T) o2).getMethodName());
528:                    }
529:                    return r;
530:                }
531:            }
532:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.