KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > optional > junit > JUnitTestRunner


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18
19 package org.apache.tools.ant.taskdefs.optional.junit;
20
21 import java.io.BufferedReader JavaDoc;
22 import java.io.ByteArrayOutputStream JavaDoc;
23 import java.io.File JavaDoc;
24 import java.io.FileInputStream JavaDoc;
25 import java.io.FileWriter JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.OutputStream JavaDoc;
28 import java.io.PrintStream JavaDoc;
29 import java.io.PrintWriter JavaDoc;
30 import java.io.StringReader JavaDoc;
31 import java.io.StringWriter JavaDoc;
32 import java.lang.reflect.Method JavaDoc;
33 import java.util.Enumeration JavaDoc;
34 import java.util.Hashtable JavaDoc;
35 import java.util.Properties JavaDoc;
36 import java.util.StringTokenizer JavaDoc;
37 import java.util.Vector JavaDoc;
38 import junit.framework.AssertionFailedError;
39 import junit.framework.Test;
40 import junit.framework.TestFailure;
41 import junit.framework.TestListener;
42 import junit.framework.TestResult;
43 import junit.framework.TestSuite;
44 import org.apache.tools.ant.BuildException;
45 import org.apache.tools.ant.Project;
46 import org.apache.tools.ant.types.Permissions;
47 import org.apache.tools.ant.util.StringUtils;
48 import org.apache.tools.ant.util.TeeOutputStream;
49
50 /**
51  * Simple Testrunner for JUnit that runs all tests of a testsuite.
52  *
53  * <p>This TestRunner expects a name of a TestCase class as its
54  * argument. If this class provides a static suite() method it will be
55  * called and the resulting Test will be run. So, the signature should be
56  * <pre><code>
57  * public static junit.framework.Test suite()
58  * </code></pre>
59  *
60  * <p> If no such method exists, all public methods starting with
61  * "test" and taking no argument will be run.
62  *
63  * <p> Summary output is generated at the end.
64  *
65  * @since Ant 1.2
66  */

67
68 public class JUnitTestRunner implements TestListener, JUnitTaskMirror.JUnitTestRunnerMirror {
69
70     /**
71      * Holds the registered formatters.
72      */

73     private Vector JavaDoc formatters = new Vector JavaDoc();
74
75     /**
76      * Collects TestResults.
77      */

78     private TestResult res;
79
80     /**
81      * Do we filter junit.*.* stack frames out of failure and error exceptions.
82      */

83     private static boolean filtertrace = true;
84
85     /**
86      * Do we send output to System.out/.err in addition to the formatters?
87      */

88     private boolean showOutput = false;
89
90     private boolean outputToFormatters = true;
91
92     /**
93      * The permissions set for the test to run.
94      */

95     private Permissions perm = null;
96
97     private static final String JavaDoc[] DEFAULT_TRACE_FILTERS = new String JavaDoc[] {
98                 "junit.framework.TestCase",
99                 "junit.framework.TestResult",
100                 "junit.framework.TestSuite",
101                 "junit.framework.Assert.", // don't filter AssertionFailure
102
"junit.swingui.TestRunner",
103                 "junit.awtui.TestRunner",
104                 "junit.textui.TestRunner",
105                 "java.lang.reflect.Method.invoke(",
106                 "sun.reflect.",
107                 "org.apache.tools.ant.",
108                 // JUnit 4 support:
109
"org.junit.",
110                 "junit.framework.JUnit4TestAdapter",
111                 // See wrapListener for reason:
112
"Caused by: java.lang.AssertionError",
113                 " more",
114         };
115
116
117     /**
118      * Do we stop on errors.
119      */

120     private boolean haltOnError = false;
121
122     /**
123      * Do we stop on test failures.
124      */

125     private boolean haltOnFailure = false;
126
127     /**
128      * Returncode
129      */

130     private int retCode = SUCCESS;
131
132     /**
133      * The TestSuite we are currently running.
134      */

135     private JUnitTest junitTest;
136
137     /** output written during the test */
138     private PrintStream JavaDoc systemError;
139
140     /** Error output during the test */
141     private PrintStream JavaDoc systemOut;
142
143     /** is this runner running in forked mode? */
144     private boolean forked = false;
145
146     /** Running more than one test suite? */
147     private static boolean multipleTests = false;
148
149     /** ClassLoader passed in in non-forked mode. */
150     private ClassLoader JavaDoc loader;
151
152     /** Do we print TestListener events? */
153     private boolean logTestListenerEvents = false;
154
155     /** Turned on if we are using JUnit 4 for this test suite. see #38811 */
156     private boolean junit4;
157
158     /**
159      * The file used to indicate that the build crashed.
160      * File will be empty in case the build did not crash.
161      */

162     private static String JavaDoc crashFile = null;
163
164     /**
165      * Constructor for fork=true or when the user hasn't specified a
166      * classpath.
167      * @param test the test to run.
168      * @param haltOnError whether to stop the run if an error is found.
169      * @param filtertrace whether to filter junit.*.* stack frames out of exceptions
170      * @param haltOnFailure whether to stop the run if failure is found.
171      */

172     public JUnitTestRunner(JUnitTest test, boolean haltOnError,
173                            boolean filtertrace, boolean haltOnFailure) {
174         this(test, haltOnError, filtertrace, haltOnFailure, false);
175     }
176
177     /**
178      * Constructor for fork=true or when the user hasn't specified a
179      * classpath.
180      * @param test the test to run.
181      * @param haltOnError whether to stop the run if an error is found.
182      * @param filtertrace whether to filter junit.*.* stack frames out of exceptions
183      * @param haltOnFailure whether to stop the run if failure is found.
184      * @param showOutput whether to send output to System.out/.err as well as formatters.
185      */

186     public JUnitTestRunner(JUnitTest test, boolean haltOnError,
187                            boolean filtertrace, boolean haltOnFailure,
188                            boolean showOutput) {
189         this(test, haltOnError, filtertrace, haltOnFailure, showOutput, false);
190     }
191
192     /**
193      * Constructor for fork=true or when the user hasn't specified a
194      * classpath.
195      * @param test the test to run.
196      * @param haltOnError whether to stop the run if an error is found.
197      * @param filtertrace whether to filter junit.*.* stack frames out of exceptions
198      * @param haltOnFailure whether to stop the run if failure is found.
199      * @param showOutput whether to send output to System.out/.err as well as formatters.
200      * @param logTestListenerEvents whether to print TestListener events.
201      * @since Ant 1.7
202      */

203     public JUnitTestRunner(JUnitTest test, boolean haltOnError,
204                            boolean filtertrace, boolean haltOnFailure,
205                            boolean showOutput, boolean logTestListenerEvents) {
206         this(test, haltOnError, filtertrace, haltOnFailure, showOutput,
207              logTestListenerEvents, null);
208     }
209
210     /**
211      * Constructor to use when the user has specified a classpath.
212      * @param test the test to run.
213      * @param haltOnError whether to stop the run if an error is found.
214      * @param filtertrace whether to filter junit.*.* stack frames out of exceptions
215      * @param haltOnFailure whether to stop the run if failure is found.
216      * @param loader the classloader to use running the test.
217      */

218     public JUnitTestRunner(JUnitTest test, boolean haltOnError,
219                            boolean filtertrace, boolean haltOnFailure,
220                            ClassLoader JavaDoc loader) {
221         this(test, haltOnError, filtertrace, haltOnFailure, false, loader);
222     }
223
224     /**
225      * Constructor to use when the user has specified a classpath.
226      * @param test the test to run.
227      * @param haltOnError whether to stop the run if an error is found.
228      * @param filtertrace whether to filter junit.*.* stack frames out of exceptions
229      * @param haltOnFailure whether to stop the run if failure is found.
230      * @param showOutput whether to send output to System.out/.err as well as formatters.
231      * @param loader the classloader to use running the test.
232      */

233     public JUnitTestRunner(JUnitTest test, boolean haltOnError,
234                            boolean filtertrace, boolean haltOnFailure,
235                            boolean showOutput, ClassLoader JavaDoc loader) {
236         this(test, haltOnError, filtertrace, haltOnFailure, showOutput,
237              false, loader);
238     }
239
240     /**
241      * Constructor to use when the user has specified a classpath.
242      * @param test the test to run.
243      * @param haltOnError whether to stop the run if an error is found.
244      * @param filtertrace whether to filter junit.*.* stack frames out of exceptions
245      * @param haltOnFailure whether to stop the run if failure is found.
246      * @param showOutput whether to send output to System.out/.err as well as formatters.
247      * @param logTestListenerEvents whether to print TestListener events.
248      * @param loader the classloader to use running the test.
249      * @since Ant 1.7
250      */

251     public JUnitTestRunner(JUnitTest test, boolean haltOnError,
252                            boolean filtertrace, boolean haltOnFailure,
253                            boolean showOutput, boolean logTestListenerEvents,
254                            ClassLoader JavaDoc loader) {
255         JUnitTestRunner.filtertrace = filtertrace;
256         this.junitTest = test;
257         this.haltOnError = haltOnError;
258         this.haltOnFailure = haltOnFailure;
259         this.showOutput = showOutput;
260         this.logTestListenerEvents = logTestListenerEvents;
261         this.loader = loader;
262     }
263
264     private PrintStream JavaDoc savedOut = null;
265
266     /**
267      * Run the test.
268      */

269     public void run() {
270         res = new TestResult();
271         res.addListener(wrapListener(this));
272         for (int i = 0; i < formatters.size(); i++) {
273             res.addListener(wrapListener((TestListener) formatters.elementAt(i)));
274         }
275
276         ByteArrayOutputStream JavaDoc errStrm = new ByteArrayOutputStream JavaDoc();
277         systemError = new PrintStream JavaDoc(errStrm);
278
279         ByteArrayOutputStream JavaDoc outStrm = new ByteArrayOutputStream JavaDoc();
280         systemOut = new PrintStream JavaDoc(outStrm);
281
282         PrintStream JavaDoc savedErr = null;
283
284         if (forked) {
285             if (!outputToFormatters) {
286                 if (!showOutput) {
287                     savedOut = System.out;
288                     savedErr = System.err;
289                     System.setOut(
290                         new PrintStream JavaDoc(
291                             new OutputStream JavaDoc() {
292                                 public void write(int b) {
293                                 }
294                             }));
295                     System.setErr(
296                         new PrintStream JavaDoc(
297                             new OutputStream JavaDoc() {
298                                 public void write(int b) {
299                                 }
300                             }));
301                 }
302             } else {
303                 savedOut = System.out;
304                 savedErr = System.err;
305                 if (!showOutput) {
306                     System.setOut(systemOut);
307                     System.setErr(systemError);
308                 } else {
309                     System.setOut(new PrintStream JavaDoc(
310                                       new TeeOutputStream(savedOut, systemOut)
311                                       )
312                                   );
313                     System.setErr(new PrintStream JavaDoc(
314                                       new TeeOutputStream(savedErr,
315                                                           systemError)
316                                       )
317                                   );
318                 }
319                 perm = null;
320             }
321         } else {
322             if (perm != null) {
323                 perm.setSecurityManager();
324             }
325         }
326
327         Test suite = null;
328         Throwable JavaDoc exception = null;
329         boolean startTestSuiteSuccess = false;
330
331         try {
332
333             try {
334                 Class JavaDoc testClass = null;
335                 if (loader == null) {
336                     testClass = Class.forName(junitTest.getName());
337                 } else {
338                     testClass = Class.forName(junitTest.getName(), true,
339                                               loader);
340                 }
341
342                 // check for a static suite method first, even when using
343
// JUnit 4
344
Method JavaDoc suiteMethod = null;
345                 try {
346                     // check if there is a suite method
347
suiteMethod = testClass.getMethod("suite", new Class JavaDoc[0]);
348                 } catch (NoSuchMethodException JavaDoc e) {
349                     // no appropriate suite method found. We don't report any
350
// error here since it might be perfectly normal.
351
}
352
353                 if (suiteMethod != null) {
354                     // if there is a suite method available, then try
355
// to extract the suite from it. If there is an error
356
// here it will be caught below and reported.
357
suite = (Test) suiteMethod.invoke(null, new Class JavaDoc[0]);
358
359                 } else {
360                     Class JavaDoc junit4TestAdapterClass = null;
361
362                     // Check for JDK 5 first. Will *not* help on JDK 1.4
363
// if only junit-4.0.jar in CP because in that case
364
// linkage of whole task will already have failed! But
365
// will help if CP has junit-3.8.2.jar:junit-4.0.jar.
366

367                     // In that case first C.fN will fail with CNFE and we
368
// will avoid UnsupportedClassVersionError.
369

370                     try {
371                         Class.forName("java.lang.annotation.Annotation");
372                         if (loader == null) {
373                             junit4TestAdapterClass =
374                                 Class.forName("junit.framework.JUnit4TestAdapter");
375                         } else {
376                             junit4TestAdapterClass =
377                                 Class.forName("junit.framework.JUnit4TestAdapter",
378                                               true, loader);
379                         }
380                     } catch (ClassNotFoundException JavaDoc e) {
381                         // OK, fall back to JUnit 3.
382
}
383                     junit4 = junit4TestAdapterClass != null;
384
385                     if (junit4) {
386                         // Let's use it!
387
suite =
388                             (Test) junit4TestAdapterClass
389                             .getConstructor(new Class JavaDoc[] {Class JavaDoc.class}).
390                             newInstance(new Object JavaDoc[] {testClass});
391                     } else {
392                         // Use JUnit 3.
393

394                         // try to extract a test suite automatically this
395
// will generate warnings if the class is no
396
// suitable Test
397
suite = new TestSuite(testClass);
398                     }
399
400                 }
401
402             } catch (Throwable JavaDoc e) {
403                 retCode = ERRORS;
404                 exception = e;
405             }
406
407             long start = System.currentTimeMillis();
408
409             fireStartTestSuite();
410             startTestSuiteSuccess = true;
411             if (exception != null) { // had an exception constructing suite
412
for (int i = 0; i < formatters.size(); i++) {
413                     ((TestListener) formatters.elementAt(i))
414                         .addError(null, exception);
415                 }
416                 junitTest.setCounts(1, 0, 1);
417                 junitTest.setRunTime(0);
418             } else {
419                 try {
420                     logTestListenerEvent("tests to run: " + suite.countTestCases());
421                     suite.run(res);
422                 } finally {
423                     if (junit4) {
424                         int[] cnts = findJUnit4FailureErrorCount(res);
425                         junitTest.setCounts(res.runCount(), cnts[0], cnts[1]);
426                     } else {
427                         junitTest.setCounts(res.runCount(), res.failureCount(),
428                                 res.errorCount());
429                     }
430                     junitTest.setRunTime(System.currentTimeMillis() - start);
431                 }
432             }
433         } finally {
434             if (perm != null) {
435                 perm.restoreSecurityManager();
436             }
437             if (savedOut != null) {
438                 System.setOut(savedOut);
439             }
440             if (savedErr != null) {
441                 System.setErr(savedErr);
442             }
443
444             systemError.close();
445             systemError = null;
446             systemOut.close();
447             systemOut = null;
448             if (startTestSuiteSuccess) {
449                 sendOutAndErr(new String JavaDoc(outStrm.toByteArray()),
450                               new String JavaDoc(errStrm.toByteArray()));
451             }
452         }
453         fireEndTestSuite();
454
455         if (retCode != SUCCESS || res.errorCount() != 0) {
456             retCode = ERRORS;
457         } else if (res.failureCount() != 0) {
458             retCode = FAILURES;
459         }
460     }
461
462     /**
463      * Returns what System.exit() would return in the standalone version.
464      *
465      * @return 2 if errors occurred, 1 if tests failed else 0.
466      */

467     public int getRetCode() {
468         return retCode;
469     }
470
471     /**
472      * Interface TestListener.
473      *
474      * <p>A new Test is started.
475      * @param t the test.
476      */

477     public void startTest(Test t) {
478         String JavaDoc testName = JUnitVersionHelper.getTestCaseName(t);
479         logTestListenerEvent("startTest(" + testName + ")");
480     }
481
482     /**
483      * Interface TestListener.
484      *
485      * <p>A Test is finished.
486      * @param test the test.
487      */

488     public void endTest(Test test) {
489         String JavaDoc testName = JUnitVersionHelper.getTestCaseName(test);
490         logTestListenerEvent("endTest(" + testName + ")");
491     }
492
493     private void logTestListenerEvent(String JavaDoc msg) {
494         PrintStream JavaDoc out = savedOut != null ? savedOut : System.out;
495         if (logTestListenerEvents) {
496             out.flush();
497             out.println(JUnitTask.TESTLISTENER_PREFIX + msg);
498             out.flush();
499         }
500     }
501
502     /**
503      * Interface TestListener for JUnit &lt;= 3.4.
504      *
505      * <p>A Test failed.
506      * @param test the test.
507      * @param t the exception thrown by the test.
508      */

509     public void addFailure(Test test, Throwable JavaDoc t) {
510         String JavaDoc testName = JUnitVersionHelper.getTestCaseName(test);
511         logTestListenerEvent("addFailure(" + testName + ", " + t.getMessage() + ")");
512         if (haltOnFailure) {
513             res.stop();
514         }
515     }
516
517     /**
518      * Interface TestListener for JUnit &gt; 3.4.
519      *
520      * <p>A Test failed.
521      * @param test the test.
522      * @param t the assertion thrown by the test.
523      */

524     public void addFailure(Test test, AssertionFailedError t) {
525         addFailure(test, (Throwable JavaDoc) t);
526     }
527
528     /**
529      * Interface TestListener.
530      *
531      * <p>An error occurred while running the test.
532      * @param test the test.
533      * @param t the error thrown by the test.
534      */

535     public void addError(Test test, Throwable JavaDoc t) {
536         String JavaDoc testName = JUnitVersionHelper.getTestCaseName(test);
537         logTestListenerEvent("addError(" + testName + ", " + t.getMessage() + ")");
538         if (haltOnError) {
539             res.stop();
540         }
541     }
542
543     /**
544      * Permissions for the test run.
545      * @since Ant 1.6
546      * @param permissions the permissions to use.
547      */

548     public void setPermissions(Permissions permissions) {
549         perm = permissions;
550     }
551
552     /**
553      * Handle a string destined for standard output.
554      * @param output the string to output
555      */

556     public void handleOutput(String JavaDoc output) {
557         if (!logTestListenerEvents && output.startsWith(JUnitTask.TESTLISTENER_PREFIX)) {
558             // ignore
559
} else if (systemOut != null) {
560             systemOut.print(output);
561         }
562     }
563
564     /**
565      * Handle input.
566      * @param buffer not used.
567      * @param offset not used.
568      * @param length not used.
569      * @return -1 always.
570      * @throws IOException never.
571      * @see org.apache.tools.ant.Task#handleInput(byte[], int, int)
572      *
573      * @since Ant 1.6
574      */

575     public int handleInput(byte[] buffer, int offset, int length)
576         throws IOException JavaDoc {
577         return -1;
578     }
579
580     /** {@inheritDoc}. */
581     public void handleErrorOutput(String JavaDoc output) {
582         if (systemError != null) {
583             systemError.print(output);
584         }
585     }
586
587     /** {@inheritDoc}. */
588     public void handleFlush(String JavaDoc output) {
589         if (systemOut != null) {
590             systemOut.print(output);
591         }
592     }
593
594     /** {@inheritDoc}. */
595     public void handleErrorFlush(String JavaDoc output) {
596         if (systemError != null) {
597             systemError.print(output);
598         }
599     }
600
601     private void sendOutAndErr(String JavaDoc out, String JavaDoc err) {
602         for (int i = 0; i < formatters.size(); i++) {
603             JUnitResultFormatter formatter =
604                 ((JUnitResultFormatter) formatters.elementAt(i));
605
606             formatter.setSystemOutput(out);
607             formatter.setSystemError(err);
608         }
609     }
610
611     private void fireStartTestSuite() {
612         for (int i = 0; i < formatters.size(); i++) {
613             ((JUnitResultFormatter) formatters.elementAt(i))
614                 .startTestSuite(junitTest);
615         }
616     }
617
618     private void fireEndTestSuite() {
619         for (int i = 0; i < formatters.size(); i++) {
620             ((JUnitResultFormatter) formatters.elementAt(i))
621                 .endTestSuite(junitTest);
622         }
623     }
624
625     /**
626      * Add a formatter.
627      * @param f the formatter to add.
628      */

629     public void addFormatter(JUnitResultFormatter f) {
630         formatters.addElement(f);
631     }
632
633     /** {@inheritDoc}. */
634     public void addFormatter(JUnitTaskMirror.JUnitResultFormatterMirror f) {
635         formatters.addElement((JUnitResultFormatter) f);
636     }
637
638     /**
639      * Entry point for standalone (forked) mode.
640      *
641      * Parameters: testcaseclassname plus parameters in the format
642      * key=value, none of which is required.
643      *
644      * <table cols="4" border="1">
645      * <tr><th>key</th><th>description</th><th>default value</th></tr>
646      *
647      * <tr><td>haltOnError</td><td>halt test on
648      * errors?</td><td>false</td></tr>
649      *
650      * <tr><td>haltOnFailure</td><td>halt test on
651      * failures?</td><td>false</td></tr>
652      *
653      * <tr><td>formatter</td><td>A JUnitResultFormatter given as
654      * classname,filename. If filename is ommitted, System.out is
655      * assumed.</td><td>none</td></tr>
656      *
657      * <tr><td>showoutput</td><td>send output to System.err/.out as
658      * well as to the formatters?</td><td>false</td></tr>
659      *
660      * <tr><td>logtestlistenerevents</td><td>log TestListener events to
661      * System.out.</td><td>false</td></tr>
662      *
663      * </table>
664      * @param args the command line arguments.
665      * @throws IOException on error.
666      */

667     public static void main(String JavaDoc[] args) throws IOException JavaDoc {
668         boolean haltError = false;
669         boolean haltFail = false;
670         boolean stackfilter = true;
671         Properties JavaDoc props = new Properties JavaDoc();
672         boolean showOut = false;
673         boolean outputToFormat = true;
674         boolean logTestListenerEvents = false;
675
676
677         if (args.length == 0) {
678             System.err.println("required argument TestClassName missing");
679             System.exit(ERRORS);
680         }
681
682         if (args[0].startsWith(Constants.TESTSFILE)) {
683             multipleTests = true;
684             args[0] = args[0].substring(Constants.TESTSFILE.length());
685         }
686
687         for (int i = 1; i < args.length; i++) {
688             if (args[i].startsWith(Constants.HALT_ON_ERROR)) {
689                 haltError = Project.toBoolean(args[i].substring(Constants.HALT_ON_ERROR.length()));
690             } else if (args[i].startsWith(Constants.HALT_ON_FAILURE)) {
691                 haltFail = Project.toBoolean(args[i].substring(Constants.HALT_ON_FAILURE.length()));
692             } else if (args[i].startsWith(Constants.FILTERTRACE)) {
693                 stackfilter = Project.toBoolean(args[i].substring(Constants.FILTERTRACE.length()));
694             } else if (args[i].startsWith(Constants.CRASHFILE)) {
695                 crashFile = args[i].substring(Constants.CRASHFILE.length());
696                 registerTestCase(Constants.BEFORE_FIRST_TEST);
697             } else if (args[i].startsWith(Constants.FORMATTER)) {
698                 try {
699                     createAndStoreFormatter(args[i].substring(Constants.FORMATTER.length()));
700                 } catch (BuildException be) {
701                     System.err.println(be.getMessage());
702                     System.exit(ERRORS);
703                 }
704             } else if (args[i].startsWith(Constants.PROPSFILE)) {
705                 FileInputStream JavaDoc in = new FileInputStream JavaDoc(args[i]
706                                                          .substring(Constants.PROPSFILE.length()));
707                 props.load(in);
708                 in.close();
709             } else if (args[i].startsWith(Constants.SHOWOUTPUT)) {
710                 showOut = Project.toBoolean(args[i].substring(Constants.SHOWOUTPUT.length()));
711             } else if (args[i].startsWith(Constants.LOGTESTLISTENEREVENTS)) {
712                 logTestListenerEvents = Project.toBoolean(
713                     args[i].substring(Constants.LOGTESTLISTENEREVENTS.length()));
714             } else if (args[i].startsWith(Constants.OUTPUT_TO_FORMATTERS)) {
715                 outputToFormat = Project.toBoolean(
716                     args[i].substring(Constants.OUTPUT_TO_FORMATTERS.length()));
717             }
718         }
719
720         // Add/overlay system properties on the properties from the Ant project
721
Hashtable JavaDoc p = System.getProperties();
722         for (Enumeration JavaDoc e = p.keys(); e.hasMoreElements();) {
723             Object JavaDoc key = e.nextElement();
724             props.put(key, p.get(key));
725         }
726
727         int returnCode = SUCCESS;
728         if (multipleTests) {
729             try {
730                 java.io.BufferedReader JavaDoc reader =
731                     new java.io.BufferedReader JavaDoc(new java.io.FileReader JavaDoc(args[0]));
732                 String JavaDoc testCaseName;
733                 int code = 0;
734                 boolean errorOccurred = false;
735                 boolean failureOccurred = false;
736                 String JavaDoc line = null;
737                 while ((line = reader.readLine()) != null) {
738                     StringTokenizer JavaDoc st = new StringTokenizer JavaDoc(line, ",");
739                     testCaseName = st.nextToken();
740                     JUnitTest t = new JUnitTest(testCaseName);
741                     t.setTodir(new File JavaDoc(st.nextToken()));
742                     t.setOutfile(st.nextToken());
743                     code = launch(t, haltError, stackfilter, haltFail,
744                                   showOut, outputToFormat,
745                                   logTestListenerEvents, props);
746                     errorOccurred = (code == ERRORS);
747                     failureOccurred = (code != SUCCESS);
748                     if (errorOccurred || failureOccurred) {
749                         if ((errorOccurred && haltError)
750                             || (failureOccurred && haltFail)) {
751                             registerNonCrash();
752                             System.exit(code);
753                         } else {
754                             if (code > returnCode) {
755                                 returnCode = code;
756                             }
757                             System.out.println("TEST " + t.getName()
758                                                + " FAILED");
759                         }
760                     }
761                 }
762             } catch (IOException JavaDoc e) {
763                 e.printStackTrace();
764             }
765         } else {
766             returnCode = launch(new JUnitTest(args[0]), haltError,
767                                 stackfilter, haltFail,
768                                 showOut, outputToFormat,
769                                 logTestListenerEvents, props);
770         }
771
772         registerNonCrash();
773         System.exit(returnCode);
774     }
775
776     private static Vector JavaDoc fromCmdLine = new Vector JavaDoc();
777
778     private static void transferFormatters(JUnitTestRunner runner,
779                                            JUnitTest test) {
780         runner.addFormatter(new JUnitResultFormatter() {
781
782             public void startTestSuite(JUnitTest suite) throws BuildException {
783             }
784
785             public void endTestSuite(JUnitTest suite) throws BuildException {
786             }
787
788             public void setOutput(OutputStream JavaDoc out) {
789             }
790
791             public void setSystemOutput(String JavaDoc out) {
792             }
793
794             public void setSystemError(String JavaDoc err) {
795             }
796
797             public void addError(Test arg0, Throwable JavaDoc arg1) {
798             }
799
800             public void addFailure(Test arg0, AssertionFailedError arg1) {
801             }
802
803             public void endTest(Test arg0) {
804             }
805
806             public void startTest(Test arg0) {
807                 registerTestCase(JUnitVersionHelper.getTestCaseName(arg0));
808             }
809         });
810         for (int i = 0; i < fromCmdLine.size(); i++) {
811             FormatterElement fe = (FormatterElement) fromCmdLine.elementAt(i);
812             if (multipleTests && fe.getUseFile()) {
813                 File JavaDoc destFile =
814                     new File JavaDoc(test.getTodir(),
815                              test.getOutfile() + fe.getExtension());
816                 fe.setOutfile(destFile);
817             }
818             runner.addFormatter((JUnitResultFormatter) fe.createFormatter());
819         }
820     }
821
822     /**
823      * Line format is: formatter=<classname>(,<pathname>)?
824      */

825     private static void createAndStoreFormatter(String JavaDoc line)
826         throws BuildException {
827         FormatterElement fe = new FormatterElement();
828         int pos = line.indexOf(',');
829         if (pos == -1) {
830             fe.setClassname(line);
831             fe.setUseFile(false);
832         } else {
833             fe.setClassname(line.substring(0, pos));
834             fe.setUseFile(true);
835             if (!multipleTests) {
836                 fe.setOutfile(new File JavaDoc(line.substring(pos + 1)));
837             } else {
838                 int fName = line.indexOf(IGNORED_FILE_NAME);
839                 if (fName > -1) {
840                     fe.setExtension(line
841                                     .substring(fName
842                                                + IGNORED_FILE_NAME.length()));
843                 }
844             }
845         }
846         fromCmdLine.addElement(fe);
847     }
848
849     /**
850      * Returns a filtered stack trace.
851      * This is ripped out of junit.runner.BaseTestRunner.
852      * @param t the exception to filter.
853      * @return the filtered stack trace.
854      */

855     public static String JavaDoc getFilteredTrace(Throwable JavaDoc t) {
856         String JavaDoc trace = StringUtils.getStackTrace(t);
857         return JUnitTestRunner.filterStack(trace);
858     }
859
860     /**
861      * Filters stack frames from internal JUnit and Ant classes
862      * @param stack the stack trace to filter.
863      * @return the filtered stack.
864      */

865     public static String JavaDoc filterStack(String JavaDoc stack) {
866         if (!filtertrace) {
867             return stack;
868         }
869         StringWriter JavaDoc sw = new StringWriter JavaDoc();
870         PrintWriter JavaDoc pw = new PrintWriter JavaDoc(sw);
871         StringReader JavaDoc sr = new StringReader JavaDoc(stack);
872         BufferedReader JavaDoc br = new BufferedReader JavaDoc(sr);
873
874         String JavaDoc line;
875         try {
876             while ((line = br.readLine()) != null) {
877                 if (!filterLine(line)) {
878                     pw.println(line);
879                 }
880             }
881         } catch (Exception JavaDoc e) {
882             return stack; // return the stack unfiltered
883
}
884         return sw.toString();
885     }
886
887     private static boolean filterLine(String JavaDoc line) {
888         for (int i = 0; i < DEFAULT_TRACE_FILTERS.length; i++) {
889             if (line.indexOf(DEFAULT_TRACE_FILTERS[i]) != -1) {
890                 return true;
891             }
892         }
893         return false;
894     }
895
896     /**
897      * @since Ant 1.6.2
898      */

899     private static int launch(JUnitTest t, boolean haltError,
900                               boolean stackfilter, boolean haltFail,
901                               boolean showOut, boolean outputToFormat,
902                               boolean logTestListenerEvents,
903                               Properties JavaDoc props) {
904         t.setProperties(props);
905         JUnitTestRunner runner =
906             new JUnitTestRunner(t, haltError, stackfilter, haltFail, showOut,
907                                 logTestListenerEvents, null);
908         runner.forked = true;
909         runner.outputToFormatters = outputToFormat;
910         transferFormatters(runner, t);
911
912         runner.run();
913         return runner.getRetCode();
914      }
915
916     /**
917      * @since Ant 1.7
918      */

919     private static void registerNonCrash()
920             throws IOException JavaDoc {
921         if (crashFile != null) {
922             FileWriter JavaDoc out = null;
923             try {
924                 out = new FileWriter JavaDoc(crashFile);
925                 out.write(Constants.TERMINATED_SUCCESSFULLY + "\n");
926                 out.flush();
927             } finally {
928                 if (out != null) {
929                     out.close();
930                 }
931             }
932         }
933     }
934
935     private static void registerTestCase(String JavaDoc testCase) {
936         if (crashFile != null) {
937             try {
938                 FileWriter JavaDoc out = null;
939                 try {
940                     out = new FileWriter JavaDoc(crashFile);
941                     out.write(testCase + "\n");
942                     out.flush();
943                 } finally {
944                     if (out != null) {
945                         out.close();
946                     }
947                 }
948             } catch (IOException JavaDoc e) {
949                 // ignored.
950
}
951         }
952     }
953
954     /**
955      * Modifies a TestListener when running JUnit 4: treats AssertionFailedError
956      * as a failure not an error.
957      *
958      * @since Ant 1.7
959      */

960     private TestListener wrapListener(final TestListener testListener) {
961         return new TestListener() {
962             public void addError(Test test, Throwable JavaDoc t) {
963                 if (junit4 && t instanceof AssertionFailedError) {
964                     // JUnit 4 does not distinguish between errors and failures
965
// even in the JUnit 3 adapter.
966
// So we need to help it a bit to retain compatibility for JUnit 3 tests.
967
testListener.addFailure(test, (AssertionFailedError) t);
968                 } else if (junit4 && t.getClass().getName().equals("java.lang.AssertionError")) {
969                     // Not strictly necessary but probably desirable.
970
// JUnit 4-specific test GUIs will show just "failures".
971
// But Ant's output shows "failures" vs. "errors".
972
// We would prefer to show "failure" for things that logically are.
973
try {
974                         String JavaDoc msg = t.getMessage();
975                         AssertionFailedError failure = msg != null
976                             ? new AssertionFailedError(msg) : new AssertionFailedError();
977                         // To compile on pre-JDK 4 (even though this should always succeed):
978
Method JavaDoc initCause = Throwable JavaDoc.class.getMethod(
979                             "initCause", new Class JavaDoc[] {Throwable JavaDoc.class});
980                         initCause.invoke(failure, new Object JavaDoc[] {t});
981                         testListener.addFailure(test, failure);
982                     } catch (Exception JavaDoc e) {
983                         // Rats.
984
e.printStackTrace(); // should not happen
985
testListener.addError(test, t);
986                     }
987                 } else {
988                     testListener.addError(test, t);
989                 }
990             }
991             public void addFailure(Test test, AssertionFailedError t) {
992                 testListener.addFailure(test, t);
993             }
994             public void addFailure(Test test, Throwable JavaDoc t) { // pre-3.4
995
if (t instanceof AssertionFailedError) {
996                     testListener.addFailure(test, (AssertionFailedError) t);
997                 } else {
998                     testListener.addError(test, t);
999                 }
1000            }
1001            public void endTest(Test test) {
1002                testListener.endTest(test);
1003            }
1004            public void startTest(Test test) {
1005                testListener.startTest(test);
1006            }
1007        };
1008    }
1009
1010    /**
1011     * Use instead of TestResult.get{Failure,Error}Count on JUnit 4,
1012     * since the adapter claims that all failures are errors.
1013     * @since Ant 1.7
1014     */

1015    private int[] findJUnit4FailureErrorCount(TestResult res) {
1016        int failures = 0;
1017        int errors = 0;
1018        Enumeration JavaDoc e = res.failures();
1019        while (e.hasMoreElements()) {
1020            e.nextElement();
1021            failures++;
1022        }
1023        e = res.errors();
1024        while (e.hasMoreElements()) {
1025            Throwable JavaDoc t = ((TestFailure) e.nextElement()).thrownException();
1026            if (t instanceof AssertionFailedError
1027                || t.getClass().getName().equals("java.lang.AssertionError")) {
1028                failures++;
1029            } else {
1030                errors++;
1031            }
1032        }
1033        return new int[] {failures, errors};
1034    }
1035
1036} // JUnitTestRunner
1037
Popular Tags