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