1 package eu.simuline.testhelpers;
2
3 import java.lang.reflect.InvocationTargetException;
4
5 import javax.swing.SwingUtilities; // wrong place?
6
7 import org.junit.runner.notification.Failure;
8 import org.junit.runner.Description;
9 import org.junit.runner.Result;
10 import org.junit.AssumptionViolatedException;
11
12 /**
13 * An {@link ExtRunListener} which notifies the GUI {@link GUIRunner}
14 * of the events occuring while running a testsuite
15 * and which comprises a textual run listener.
16 *
17 * Created: Sat Jun 3 17:17:23 2006
18 *
19 * @author <a href="mailto:ernst.reissner@simuline.eu">Ernst Reissner</a>
20 * @version 1.0
21 */
22 public final class GUIRunListener extends ExtRunListener {
23
24
25 /* -------------------------------------------------------------------- *
26 * fields. *
27 * -------------------------------------------------------------------- */
28
29 private final GUIRunner guiRunner;
30
31 private TestCase testCase;
32
33
34 /* -------------------------------------------------------------------- *
35 * constructor. *
36 * -------------------------------------------------------------------- */
37
38 public GUIRunListener(GUIRunner guiRunner) {
39 this.guiRunner = guiRunner;
40 }
41
42 /* -------------------------------------------------------------------- *
43 * methods. *
44 * -------------------------------------------------------------------- */
45
46
47 /**
48 * Called before any tests have been run.
49 * Updates the enablement of the GUI-Actions
50 * and then delegates to
51 * {@link GUIRunner#testRunStarted(Description)}.
52 * Updates the enablement of the GUI-Actions
53 * and ***** OVERWRITTEN FOR ALL
54 *
55 * @param desc
56 * describes the tests to be run
57 */
58 public void testRunStarted(final Description desc)
59 throws Exception { //NOPMD
60 assert !SwingUtilities.isEventDispatchThread();
61
62 Runnable runnable = new Runnable() {
63 public void run() {
64 GUIRunListener.this.guiRunner.testRunStarted(desc);
65 }
66 };
67 SwingUtilities.invokeAndWait(runnable);
68 System.out.println("..testRunStarted");
69 }
70
71 /**
72 * Called when all tests have finished.
73 * Prints a statistics on the result to the standard output,
74 * a summary to the status bar of the GUI
75 * and updates the enablement of the GUI-Actions.
76 *
77 * @param result
78 * the summary of the test run, including all the tests that failed
79 */
80 // api-docs inherited from class RunListener
81 public void testRunFinished(final Result result) throws Exception { //NOPMD
82 assert !SwingUtilities.isEventDispatchThread();
83 // output text
84 // super.testRunFinished(result);
85
86 Runnable runnable = new Runnable() {
87 public void run() {
88 GUIRunListener.this.guiRunner
89 .testRunFinished(result.getRunTime());
90 }
91 };
92 SwingUtilities.invokeAndWait(runnable);
93 System.out.println("..testRunFinished");
94 }
95
96 /**
97 * Called when a test suite is about to be started.
98 * If this method is called for a given {@link Description},
99 * then {@link #testSuiteFinished(Description)}
100 * will also be called for the same {@link Description}.
101 * <p>
102 * Note that not all runners will call this method, so runners should
103 * be prepared to handle {@link #testStarted(Description)} calls for tests
104 * where there was no cooresponding {@link #testSuiteStarted(Description)}
105 * call for the parent {@link Description}.
106 *
107 * @param desc
108 * the description of the test suite that is about to be run
109 * (generally a class name)
110 * @since 4.13
111 */
112 // api-docs inherited from class RunListener
113 public void testSuiteStarted(Description desc) throws Exception { //NOPMD
114 assert !SwingUtilities.isEventDispatchThread();
115 // **** at the moment no actions on the GUI
116 }
117
118 /**
119 * Called when a test suite has finished,
120 * whether the test suite succeeds or fails.
121 * This method will not be called for a given {@link Description}
122 * unless {@link #testSuiteStarted(Description)} was called
123 * for the same {@link Description}.
124 *
125 * @param desc
126 * the description of the test suite that just ran
127 * @since 4.13
128 */
129 public void testSuiteFinished(Description desc) throws Exception { //NOPMD
130 assert !SwingUtilities.isEventDispatchThread();
131 // output text
132 // **** at the moment no actions on the GUI
133 }
134
135 /**
136 * Called when an atomic test is about to be started.
137 * An ignored test is never started.
138 *
139 * @param desc
140 * the description of the test that is about to be started
141 * (generally a class and method name)
142 * @see #testIgnored(Description)
143 */
144 // api-docs inherited from class RunListener
145 public void testStarted(final Description desc) throws Exception { //NOPMD
146 assert !SwingUtilities.isEventDispatchThread();
147
148
149 Runnable runnable = new Runnable() {
150 public void run() {
151 GUIRunListener.this.testCase =
152 GUIRunListener.this.guiRunner
153 .noteTestStartedI(Quality.Started);
154 }
155 };
156 SwingUtilities.invokeAndWait(runnable);
157 System.out.println("..testStarted");
158 }
159
160 /**
161 * Called when an atomic test has finished,
162 * whether the test succeeds or fails.
163 * This method must be invoked after a test has been started
164 * which was indicated by {@link #testStarted(Description)} before.
165 * An ignored test is never finished.
166 *
167 * @param desc
168 * the description of the test that just ran
169 * @see #testIgnored(Description)
170 */
171 public void testFinished(final Description desc) throws Exception { //NOPMD
172 assert !SwingUtilities.isEventDispatchThread();
173
174 Runnable runnable = new Runnable() {
175 public void run() {
176 GUIRunListener.this.testCase.setFinished();
177 GUIRunListener.this.guiRunner
178 .noteReportResult(GUIRunListener.this.testCase);
179 }
180 };
181
182 SwingUtilities.invokeAndWait(runnable);
183 System.out.println("..testFinished");
184 }
185
186 /**
187 * Called when an atomic test fails to execute properly
188 * throwing a Throwable.
189 * This method is invoked after {@link #testStarted(Description)}
190 * and before {@link #testFinished(Description)}
191 * with the according description.
192 * In case of a failed assumption, instead of this method
193 * {@link #testAssumptionFailure(Failure)} is invoked
194 * for the according test.
195 *
196 * @param failure
197 * describes the test that failed and the exception that was thrown
198 */
199 public void testFailure(final Failure failure) throws Exception { //NOPMD
200 assert !SwingUtilities.isEventDispatchThread();
201 // GUI ignores failures in the test mechanism.
202 // **** this may be inappropriate.
203 if (failure.getDescription().equals(Description.TEST_MECHANISM)) {
204 return;
205 }
206 Runnable runnable = new Runnable() {
207 public void run() {
208 GUIRunListener.this.testCase.setFailure(failure);
209 GUIRunListener.this.guiRunner.setStatus("testFailure: "
210 + failure.getException());
211 }
212 };
213 SwingUtilities.invokeAndWait(runnable);
214 System.out.println("..testFailure");
215 }
216
217
218 /**
219 * Called when an atomic test flags
220 * that it assumes a condition that is false.
221 * This is treated as ignored with the description of the failure.
222 * This method is invoked after {@link #testStarted(Description)}
223 * and before {@link #testFinished(Description)}
224 * with the according description.
225 * A failed assertion does not count as a failure
226 * and so {@link #testFailure(Failure)} is not invoked
227 * for the according test.
228 * <p>
229 * CAUTION: Although a failed assertion is like an ignored test,
230 * {@link #testRunFinished(Result)} does not count this as ignored test
231 * but rather than a passed test.
232 *
233 * @param failure
234 * describes the test that failed
235 * and the {@link AssumptionViolatedException} that was thrown.
236 * @see #testIgnored(Description)
237 */
238 public void testAssumptionFailure(final Failure failure) {
239 assert !SwingUtilities.isEventDispatchThread();
240
241 Runnable runnable = new Runnable() {
242 public void run() {
243 GUIRunListener.this.testCase.setAssumptionFailure(failure);
244 GUIRunListener.this.guiRunner
245 .setStatus("testAssumptionFailure: "
246 + failure.getException());
247 }
248 };
249
250 try {
251 SwingUtilities.invokeAndWait(runnable);
252 } catch (InterruptedException e) {
253 e.printStackTrace();
254 } catch (InvocationTargetException e) {
255 e.printStackTrace();
256 }
257 System.out.println("..testAssumptionFailure");
258 }
259
260 /**
261 * Called when a test will not be run,
262 * generally because a test method is annotated
263 * with <code>@Ignored</code>.
264 * This implies
265 * that neither {@link #testStarted(Description)}
266 * nor {@link #testFinished(Description)} are invoked
267 * for the according test.
268 * This in turn implies that neither {@link #testFailure(Failure)}
269 * nor {@link #testAssumptionFailure(Failure)} are invoked.
270 * are invoked.
271 *
272 * @param desc
273 * describes the test that will not be run
274 */
275 public void testIgnored(final Description desc) throws Exception { //NOPMD
276 assert !SwingUtilities.isEventDispatchThread();
277
278 Runnable runnable = new Runnable() {
279 public void run() {
280 GUIRunListener.this.testCase =
281 GUIRunListener.this.guiRunner
282 .noteTestStartedI(Quality.Ignored);
283 GUIRunListener.this.guiRunner
284 .noteReportResult(GUIRunListener.this.testCase);
285 }
286 };
287 SwingUtilities.invokeAndWait(runnable);
288 System.out.println("...testIgnored");
289 }
290
291 // homemade extension
292 /**
293 * Invoked for stop and for break originated by the user.
294 */
295 // not clear which test has been aborted.
296 public void testRunAborted() {
297 assert !SwingUtilities.isEventDispatchThread();
298
299 Runnable runnable = new Runnable() {
300 public void run() {
301 GUIRunListener.this.guiRunner.testRunAborted();
302 }
303 };
304 try {
305 SwingUtilities.invokeAndWait(runnable);
306 } catch (InterruptedException e) {
307 e.printStackTrace();
308 } catch (InvocationTargetException e) {
309 e.printStackTrace();
310 }
311 System.out.println("..testRunAborted(");
312 }
313
314 // homemade extension
315 /**
316 * Invoked if a test class is loaded defining a testsuite
317 * described by <code>desc</code>.
318 */
319 public void testClassStructureLoaded(final Description desc) {
320 Runnable runnable = new Runnable() {
321 public void run() {
322 GUIRunListener.this.guiRunner
323 .testClassStructureLoaded(desc);
324 }
325 };
326 try {
327 SwingUtilities.invokeAndWait(runnable);
328 } catch (InterruptedException e) {
329 e.printStackTrace();
330 } catch (InvocationTargetException e) {
331 e.printStackTrace();
332 }
333 System.out.println("..testClassStructureLoaded(");
334 }
335 }
336