1 package eu.simuline.testhelpers;
2
3 import org.junit.runner.notification.Failure;
4
5 import org.junit.runner.Description;
6 import org.junit.runner.Result;
7
8 import java.util.Iterator;
9 import org.junit.AssumptionViolatedException;
10
11 /**
12 * A simple RunListener which notifies of the events while running tests
13 * by text output.
14 *
15 * Created: Wed Jun 7 16:41:14 2006
16 *
17 * @author <a href="mailto:ernst.reissner@simuline.eu">Ernst Reissner</a>
18 * @version 1.0
19 */
20 public final class TextRunListener extends ExtRunListener {
21
22 /* -------------------------------------------------------------------- *
23 * constructor. *
24 * -------------------------------------------------------------------- */
25
26 /**
27 * Creates a new <code>TextRunListener</code> instance.
28 *
29 */
30 public TextRunListener() {
31 // is empty.
32 }
33
34 /* -------------------------------------------------------------------- *
35 * methods. *
36 * -------------------------------------------------------------------- */
37
38 /**
39 * Returns a string representation of <code>desc</code>:
40 * For atomic tests the display name,
41 * for suites an xml-style description.
42 */
43 private static String desc2string(Description desc) {
44 StringBuffer buf = new StringBuffer();
45 if (desc.isSuite()) {
46 buf.append("<Suite name=\"");
47 buf.append(desc.getDisplayName());
48 buf.append("\">\n");
49 Description child;
50 Iterator<Description> iter = desc.getChildren().iterator();
51 assert iter.hasNext();
52 child = iter.next();
53 buf.append(desc2string(child));
54 while (iter.hasNext()) {
55 child = iter.next();
56 buf.append(", \n");
57 buf.append(desc2string(child));
58 }
59 buf.append("\n</Suite>");
60 } else {
61 assert desc.isTest();
62 buf.append(desc.getDisplayName());
63 }
64 return buf.toString();
65 }
66
67
68 /**
69 * Called before any tests
70 * of a suite described by <code>desc</code> have been run.
71 * This may be called on an arbitrary thread.
72 *
73 * @param desc
74 * describes the suite of tests to be run.
75 */
76 // api-docs inherited from class RunListener
77 public void testRunStarted(Description desc) throws Exception { //NOPMD
78 System.out.println("T testRunStarted(..." + desc2string(desc));
79 }
80
81 /**
82 * Called when all tests of the suite
83 * announced by {@link #testRunStarted(Description)} have finished.
84 * This may be called on an arbitrary thread.
85 * <p>
86 * Prints a statistics on the result of the test suite
87 * to the standard output.
88 *
89 * @param result
90 * the summary of the outcoming of the suite of tests run,
91 * including all the tests that failed
92 */
93 // api-docs inherited from class RunListener
94 public void testRunFinished(Result result) throws Exception { //NOPMD
95 System.out.println("T testRunFinished(..." + result);
96 System.out.println("Statistics: ");
97 System.out.println("runs: " + result.getRunCount());
98 System.out.println("ignored: " + result.getIgnoreCount());
99 System.out.println("failures: " + result.getFailureCount());
100 System.out.println("time elapsed: " + result.getRunTime() + "ms");
101 // **** strange:
102 // runs seem without ignores
103 // failures seem all runs which did not succeed,
104 // i.e. test could not be executed or failed.
105 // **** only in singular tests with GUI:
106 // ignored seem to be also failures
107 }
108
109 // api-docs inherited from class RunListener
110 /**
111 * Called when a test suite is about to be started.
112 * If this method is called for a given {@link Description},
113 * then {@link #testSuiteFinished(Description)}
114 * will also be called for the same {@code Description}.
115 * <p>
116 * Note that not all runners will call this method, so runners should
117 * be prepared to handle {@link #testStarted(Description)} calls for tests
118 * where there was no corresponding {@link #testSuiteStarted(Description)}
119 * call for the parent {@link Description}.
120 *
121 * @param desc
122 * the description of the test suite that is about to be run
123 * (generally a class name)
124 * @since 4.13
125 */
126 public void testSuiteStarted(Description desc) throws Exception { //NOPMD
127 System.out.println("S testSuiteStarted(... " + desc);
128 }
129
130 /**
131 * Called when a test suite has finished,
132 * whether the test suite succeeds or fails.
133 * This method will not be called for a given {@link Description}
134 * unless {@link #testSuiteStarted(Description)} was called
135 * for the same {@link Description}.
136 *
137 * @param desc
138 * the description of the test suite that just ran
139 * @since 4.13
140 */
141 public void testSuiteFinished(Description desc) throws Exception { //NOPMD
142 System.out.println("S testSuiteFinished(... " + desc);
143 }
144
145 /**
146 * Called when an atomic test is about to be started.
147 * An ignored test is never started.
148 *
149 * @param desc
150 * the description of the test that is about to be run
151 * (generally a class and method name)
152 * @see #testIgnored(Description)
153 */
154 // api-docs inherited from class RunListener
155 public void testStarted(Description desc) throws Exception { //NOPMD
156 System.out.println("T testStarted(... " + desc);
157 }
158
159 /**
160 * Called when an atomic test has finished,
161 * whether the test succeeds or fails.
162 * This method must be invoked after a test has been started
163 * which was indicated by {@link #testStarted(Description)} before.
164 * An ignored test is never finished.
165 *
166 * @param desc
167 * the description of the test that just ran
168 * @see #testIgnored(Description)
169 */
170 // api-docs inherited from class RunListener
171 public void testFinished(Description desc) throws Exception { //NOPMD
172 System.out.println("T testFinished( " + desc);
173 }
174
175 /**
176 * Called when an atomic test fails to execute properly
177 * throwing a Throwable, or when a listener throws an exception.
178 * <p>
179 * In the case of a failure of an atomic test,
180 * this method is invoked after {@link #testStarted(Description)}
181 * and before {@link #testFinished(Description)}
182 * with the according description of <code>failure</code>
183 * from the same thread that called {@link #testStarted(Description)}.
184 * In case of a failed assumption, instead of this method
185 * {@link #testAssumptionFailure(Failure)} is invoked
186 * for the according test.
187 * <p>
188 * In the case of a listener throwing an exception,
189 * this method will be called with the description of <code>failure</code>
190 * given by {@link Description#TEST_MECHANISM},
191 * and may be called on an arbitrary thread.
192 *
193 * @param failure
194 * describes the test that failed and the exception that was thrown
195 * or indicates that a listener has thrown an exception
196 * and the according exception.
197 */
198 // api-docs inherited from class RunListener
199 public void testFailure(Failure failure) throws Exception { //NOPMD
200 // description and exception
201 if (failure.getDescription().equals(Description.TEST_MECHANISM)) {
202 System.out.println("FRAMEWORK testFailure( " + failure);
203 }
204
205 System.out.println("T testFailure( " + failure);
206 }
207
208 /**
209 * Called when an atomic test flags
210 * that it assumes a condition that is false.
211 * This is treated as ignored with the description of the failure.
212 * This method is invoked after {@link #testStarted(Description)}
213 * and before {@link #testFinished(Description)}
214 * with the according description of <code>failure</code>.
215 * A failed assertion does not count as a failure
216 * and so {@link #testFailure(Failure)} is not invoked
217 * for the according test.
218 * <p>
219 * CAUTION: Although a failed assertion is like an ignored test,
220 * {@link #testRunFinished(Result)} does not count this as ignored test
221 * but rather than a passed test.
222 *
223 * @param failure
224 * describes the test that failed
225 * and the {@link AssumptionViolatedException} that was thrown.
226 * @see #testIgnored(Description)
227 */
228 public void testAssumptionFailure(Failure failure) {
229 // description and exception
230 assert failure.getException() instanceof AssumptionViolatedException;
231 System.out.println("T testAssumptionFailure(" + failure);
232 }
233
234 /**
235 * Called when a test will not be run,
236 * generally because a test method is annotated
237 * with {@link org.junit.Ignore}.
238 * This implies
239 * that neither {@link #testStarted(Description)}
240 * nor {@link #testFinished(Description)} are invoked
241 * for the according test.
242 * This in turn implies that neither {@link #testFailure(Failure)}
243 * nor {@link #testAssumptionFailure(Failure)} are invoked.
244 *
245 * @param desc
246 * describes the test that will not be run
247 */
248 // api-docs inherited from class RunListener
249 public void testIgnored(Description desc) throws Exception { //NOPMD
250 System.out.println("T testIgnored( " + desc);
251 }
252
253 // homemade extension
254 /**
255 * Invoked for stop and for break originated by the user.
256 */
257 // not clear which test has been aborted.
258 public void testRunAborted() {
259 // output text
260 System.out.println("S testRunAborted(");
261 }
262
263 // homemade extension
264 /**
265 * Invoked if a test class is loaded defining a testsuite
266 * described by <code>desc</code>.
267 */
268 public void testClassStructureLoaded(final Description desc) {
269 System.out.println("S testClassStructureLoaded(" + desc);
270 }
271 }