VerboseReporter.java revision 6937ff54680f776064a6b1eb09d1bd84ed402a2f
1/*
2 * To change this template, choose Tools | Templates
3 * and open the template in the editor.
4 */
5package org.testng.reporters;
6
7import java.lang.reflect.Method;
8import java.util.List;
9import org.testng.ITestContext;
10import org.testng.ITestNGMethod;
11import org.testng.ITestResult;
12import org.testng.TestListenerAdapter;
13import org.testng.internal.Utils;
14
15/**
16 *
17 * @author Lukas Jungmann
18 */
19//topic for discussion with Cedric
20//would be better to merge this class and org.testng.reporters.TextReporter
21//or keep this as separate listener?
22//main diferences are:
23// - format of the message being logged
24// - message is logged immediately instead of in onFinish event
25// - all messages have specific prefix
26public class VerboseReporter extends TestListenerAdapter {
27
28    public static final String LISTENER_PREFIX = "[VerboseTestNG] ";
29    private String testName;
30    private final String prefix;
31
32    public VerboseReporter() {
33        this(LISTENER_PREFIX);
34    }
35
36    public VerboseReporter(String prefix) {
37       this.prefix = prefix;
38    }
39
40    @Override
41    public void beforeConfiguration(ITestResult tr) {
42        super.beforeConfiguration(tr);
43        logResult("INVOKING CONFIGURATION", detailedMethodName(tr.getMethod(), true));
44    }
45
46    @Override
47    public void onConfigurationFailure(ITestResult tr) {
48        super.onConfigurationFailure(tr);
49        Throwable ex = tr.getThrowable();
50        String stackTrace = "";
51        if (ex != null) {
52            stackTrace = Utils.stackTrace(ex, false)[0];
53        }
54        long duration = tr.getEndMillis() - tr.getStartMillis();
55        logResult("FAILED CONFIGURATION", detailedMethodName(tr.getMethod(), true), tr.getMethod().getDescription(), stackTrace, tr.getParameters(), tr.getMethod().getMethod().getParameterTypes(), duration);
56    }
57
58    @Override
59    public void onConfigurationSkip(ITestResult tr) {
60        super.onConfigurationSkip(tr);
61        long duration = tr.getEndMillis() - tr.getStartMillis();
62        logResult("SKIPPED CONFIGURATION", detailedMethodName(tr.getMethod(), true), tr.getMethod().getDescription(), null, tr.getParameters(), tr.getMethod().getMethod().getParameterTypes(), duration);
63    }
64
65    @Override
66    public void onConfigurationSuccess(ITestResult tr) {
67        super.onConfigurationSuccess(tr);
68        long duration = tr.getEndMillis() - tr.getStartMillis();
69        logResult("PASSED CONFIGURATION", detailedMethodName(tr.getMethod(), true), tr.getMethod().getDescription(), null, tr.getParameters(), tr.getMethod().getMethod().getParameterTypes(), duration);
70    }
71
72    @Override
73    public void onTestFailure(ITestResult tr) {
74        super.onTestFailure(tr);
75        Throwable ex = tr.getThrowable();
76        String stackTrace = "";
77        if (ex != null) {
78            stackTrace = Utils.stackTrace(ex, false)[0];
79        }
80        logResult("FAILED", tr, stackTrace);
81    }
82
83    @Override
84    public void onTestFailedButWithinSuccessPercentage(ITestResult tr) {
85        super.onTestFailedButWithinSuccessPercentage(tr);
86        logResult("PASSED with failures", tr, null);
87    }
88
89    @Override
90    public void onTestSkipped(ITestResult tr) {
91        super.onTestSkipped(tr);
92        Throwable throwable = tr.getThrowable();
93        logResult("SKIPPED", tr, throwable != null ? Utils.stackTrace(throwable, false)[0] : null);
94    }
95
96    @Override
97    public void onTestSuccess(ITestResult tr) {
98        super.onTestSuccess(tr);
99        logResult("PASSED", tr, null);
100    }
101
102    @Override
103    public void onStart(ITestContext ctx) {
104        testName = ctx.getName();//ctx.getSuite().getXmlSuite().getFileName();
105        logResult("RUNNING", "Suite: \"" + testName + "\" containing \"" + ctx.getAllTestMethods().length + "\" Tests (config: " + ctx.getSuite().getXmlSuite().getFileName() + ")");
106
107    }
108
109    @Override
110    public void onFinish(ITestContext context) {
111        logResults();
112        testName = null;
113    }
114
115    @Override
116    public void onTestStart(ITestResult tr) {
117        logResult("INVOKING", detailedMethodName(tr.getMethod(), true));
118    }
119
120    private ITestNGMethod[] resultsToMethods(List<ITestResult> results) {
121        ITestNGMethod[] result = new ITestNGMethod[results.size()];
122        int i = 0;
123        for (ITestResult tr : results) {
124            result[i++] = tr.getMethod();
125        }
126        return result;
127    }
128
129    private void logResults() {
130        //
131        // Log test summary
132        //
133        ITestNGMethod[] ft = resultsToMethods(getFailedTests());
134        StringBuffer logBuf = new StringBuffer("\n===============================================\n");
135        logBuf.append("    ").append(getName()).append("\n");
136        logBuf.append("    Tests run: ").append(Utils.calculateInvokedMethodCount(getAllTestMethods())).append(", Failures: ").append(Utils.calculateInvokedMethodCount(ft)).append(", Skips: ").append(Utils.calculateInvokedMethodCount(resultsToMethods(getSkippedTests())));
137        int confFailures = getConfigurationFailures().size();
138        int confSkips = getConfigurationSkips().size();
139//        if (confFailures > 0 || confSkips > 0) {
140            logBuf.append("\n").append("    Configuration Failures: ").append(confFailures).append(", Skips: ").append(confSkips);
141//        }
142        logBuf.append("\n===============================================");
143        logResult("", logBuf.toString());
144    }
145
146    private String getName() {
147        return testName;
148    }
149
150    private void logResult(String status, ITestResult tr, String stackTrace) {
151        long duration = tr.getEndMillis() - tr.getStartMillis();
152        logResult(status, detailedMethodName(tr.getMethod(), true), tr.getMethod().getDescription(), stackTrace, tr.getParameters(), tr.getMethod().getMethod().getParameterTypes(), duration);
153    }
154
155    private void logResult(String status, String message) {
156        StringBuffer buf = new StringBuffer();
157        if (Utils.isStringNotBlank(status)) {
158            buf.append(status).append(": ");
159        }
160        buf.append(message);
161//        System.out.println("LOG: " + buf.toString());
162        //prefix all output lines
163        System.out.println(buf.toString().replaceAll("(?m)^", prefix));
164    }
165
166    private void logResult(String status, String name, String description, String stackTrace, Object[] params, Class[] paramTypes, long duration) {
167        StringBuffer msg = new StringBuffer(name);
168        if (null != params && params.length > 0) {
169            msg.append("(value(s): ");
170            // The error might be a data provider parameter mismatch, so make
171            // a special case here
172            if (params.length != paramTypes.length) {
173                msg.append(name + ": Wrong number of arguments were passed by " + "the Data Provider: found " + params.length + " but " + "expected " + paramTypes.length + ")");
174            } else {
175                for (int i = 0; i < params.length; i++) {
176                    if (i > 0) {
177                        msg.append(", ");
178                    }
179                    msg.append(Utils.toString(params[i], paramTypes[i]));
180                }
181                msg.append(")");
182            }
183        }
184        msg.append(" finished in ");
185        msg.append(duration);
186        msg.append(" ms");
187        if (!Utils.isStringEmpty(description)) {
188            msg.append("\n");
189            for (int i = 0; i < status.length() + 2; i++) {
190                msg.append(" ");
191            }
192            msg.append(description);
193        }
194        if (!Utils.isStringEmpty(stackTrace)) {
195            msg.append("\n").append(stackTrace.substring(0, stackTrace.lastIndexOf(System.getProperty("line.separator"))));
196        }
197        logResult(status, msg.toString());
198    }
199
200    @Deprecated
201    //perhaps should rather to adopt the original method
202    private String detailedMethodName(ITestNGMethod method, boolean fqn) {
203        Method m = method.getMethod();
204        StringBuffer buf = new StringBuffer();
205        buf.append("\"");
206        if (getName() != null) {
207            buf.append(getName());
208        } else {
209            buf.append("UNKNOWN");
210        }
211        buf.append("\"");
212        buf.append(" - ");
213        if (method.isBeforeSuiteConfiguration()) {
214            buf.append("@BeforeSuite ");
215        } else if (method.isBeforeTestConfiguration()) {
216            buf.append("@BeforeTest ");
217        } else if (method.isBeforeClassConfiguration()) {
218            buf.append("@BeforeClass ");
219        } else if (method.isBeforeGroupsConfiguration()) {
220            buf.append("@BeforeGroups ");
221        } else if (method.isBeforeMethodConfiguration()) {
222            buf.append("@BeforeMethod ");
223        } else if (method.isAfterMethodConfiguration()) {
224            buf.append("@AfterMethod ");
225        } else if (method.isAfterGroupsConfiguration()) {
226            buf.append("@AfterGroups ");
227        } else if (method.isAfterClassConfiguration()) {
228            buf.append("@AfterClass ");
229        } else if (method.isAfterTestConfiguration()) {
230            buf.append("@AfterTest ");
231        } else if (method.isAfterSuiteConfiguration()) {
232            buf.append("@AfterSuite ");
233        }
234        buf.append(m.getDeclaringClass().getName());
235        buf.append(".");
236        buf.append(m.getName());
237        buf.append("(");
238        int i = 0;
239        for (Class<?> p : m.getParameterTypes()) {
240            if (i++ > 0) {
241                buf.append(", ");
242            }
243            buf.append(p.getName());
244        }
245        buf.append(")");
246        return buf.toString();//buf.append(fqn ? method.toString() : method.getMethodName()).toString();
247    }
248
249    @Override
250    public String toString() {
251        return "VerboseReporter{" + "testName=" + testName + '}';
252    }
253
254}
255