There is no automatic testcase for this, but if your run ant -f src/etc/testcases/taskdefs/optional/junit.xml -Dshowoutput=off ant -f src/etc/testcases/taskdefs/optional/junit.xml -Dshowoutput=on you'll see it in action. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@272496 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -4,10 +4,6 @@ Changes from Ant 1.4.1 to current CVS version | |||
| Changes that could break older environments: | |||
| -------------------------------------------- | |||
| * Shipped XML parser is now Xerces 2.0.1 along with the XML Parser APIs. | |||
| XML Parser APIs is a separate jar that contains the necessary | |||
| JAXP/DOM/SAX classes. | |||
| * Important: Single $ signs are no longer silently stripped! | |||
| Before you panic that we have broken all your build files, we have kept | |||
| the old "$$" -> "$" behaviour. So only build files which accidentally had | |||
| @@ -16,6 +12,10 @@ Changes that could break older environments: | |||
| build file which works on ant versions 1.4.1 or earlier, stay with | |||
| the double $$ sign rule. | |||
| * Shipped XML parser is now Xerces 2.0.1 along with the XML Parser APIs. | |||
| XML Parser APIs is a separate jar that contains the necessary | |||
| JAXP/DOM/SAX classes. | |||
| * <telnet> was fixed to expand properties inside nested <read> and | |||
| <write> elements; before this only happened when you assigned the text | |||
| to the string attribute. If you had $ signs in the string, they may | |||
| @@ -321,6 +321,11 @@ Other changes: | |||
| * org.apache.tools.ant.XmlLogger now is a BuildLogger, rather than just | |||
| a BuildListener. It can operate in either mode successfully. | |||
| * <junit> has a new attribute "showoutput". If set to true, output | |||
| generated by tests will be sent to Ant's logging system as well as | |||
| to the formatters (instead of sending it to the formatters | |||
| exclusively). | |||
| Changes from Ant 1.4 to Ant 1.4.1 | |||
| =========================================== | |||
| @@ -340,27 +340,6 @@ | |||
| <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | |||
| Stefan, others welcome | |||
| </font> | |||
| </td> | |||
| </tr> | |||
| <tr> | |||
| <td bgcolor="#a0ddf0" colspan="" rowspan="" | |||
| valign="top" align="left"> | |||
| <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | |||
| JUnit's System.err/.out handling | |||
| </font> | |||
| </td> | |||
| <td bgcolor="#a0ddf0" colspan="" rowspan="" | |||
| valign="top" align="left"> | |||
| <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | |||
| Currently this is coupled to SummaryResultFormatter - | |||
| no SummaryFormatter, no output. Want to decouple it. | |||
| </font> | |||
| </td> | |||
| <td bgcolor="#a0ddf0" colspan="" rowspan="" | |||
| valign="top" align="left"> | |||
| <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | |||
| Stefan, others welcome | |||
| </font> | |||
| </td> | |||
| </tr> | |||
| <tr> | |||
| @@ -494,7 +473,28 @@ | |||
| <td bgcolor="#a0ddf0" colspan="" rowspan="" | |||
| valign="top" align="left"> | |||
| <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | |||
| Stefan, others welcome | |||
| Stefan | |||
| </font> | |||
| </td> | |||
| </tr> | |||
| <tr> | |||
| <td bgcolor="#a0ddf0" colspan="" rowspan="" | |||
| valign="top" align="left"> | |||
| <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | |||
| JUnit's System.err/.out handling | |||
| </font> | |||
| </td> | |||
| <td bgcolor="#a0ddf0" colspan="" rowspan="" | |||
| valign="top" align="left"> | |||
| <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | |||
| showoutput attribute has been added - doesn't work in | |||
| some cases yet (same reason as bug PR 7980) | |||
| </font> | |||
| </td> | |||
| <td bgcolor="#a0ddf0" colspan="" rowspan="" | |||
| valign="top" align="left"> | |||
| <font color="#000000" size="-1" face="arial,helvetica,sanserif"> | |||
| Stefan | |||
| </font> | |||
| </td> | |||
| </tr> | |||
| @@ -135,6 +135,13 @@ elements</a>).</p> | |||
| the tests and JUnit to the classpath in forked mode.</td> | |||
| <td align="center" valign="top">No; default is <code>true</code>.</td> | |||
| </tr> | |||
| <tr> | |||
| <td valign="top">showoutput</td> | |||
| <td valign="top">Send any output generated by tests to Ant's | |||
| logging system as well as to the formatters. By default only the | |||
| formatters receive the output.</td> | |||
| <td align="center" valign="top">No</td> | |||
| </tr> | |||
| </table> | |||
| <p>By using the <code>errorproperty</code> and <code>failureproperty</code> | |||
| @@ -1,34 +1,39 @@ | |||
| <?xml version="1.0"?> | |||
| <project name="junit-test" basedir="." default="outputTests"> | |||
| <property name="showoutput" value="false" /> | |||
| <path id="test"> | |||
| <pathelement path="${java.class.path}" /> | |||
| <pathelement location="../../../../../build/testcases" /> | |||
| </path> | |||
| <target name="testForkedOutput"> | |||
| <junit fork="yes" haltonerror="true" haltonfailure="true"> | |||
| <junit fork="yes" haltonerror="true" haltonfailure="true" | |||
| showoutput="${showoutput}"> | |||
| <test name="org.example.junit.Output" /> | |||
| <classpath refid="test" /> | |||
| </junit> | |||
| </target> | |||
| <target name="testNonForkedOutput"> | |||
| <junit fork="false" haltonerror="true" haltonfailure="true"> | |||
| <junit fork="false" haltonerror="true" haltonfailure="true" | |||
| showoutput="${showoutput}"> | |||
| <test name="org.example.junit.Output" /> | |||
| <classpath refid="test" /> | |||
| </junit> | |||
| </target> | |||
| <target name="testForkedThreadedOutput"> | |||
| <junit fork="yes" haltonerror="true" haltonfailure="true"> | |||
| <junit fork="yes" haltonerror="true" haltonfailure="true" | |||
| showoutput="${showoutput}"> | |||
| <test name="org.example.junit.ThreadedOutput" /> | |||
| <classpath refid="test" /> | |||
| </junit> | |||
| </target> | |||
| <target name="testNonForkedThreadedOutput"> | |||
| <junit fork="false" haltonerror="true" haltonfailure="true"> | |||
| <junit fork="false" haltonerror="true" haltonfailure="true" | |||
| showoutput="${showoutput}"> | |||
| <test name="org.example.junit.ThreadedOutput" /> | |||
| <classpath refid="test" /> | |||
| </junit> | |||
| @@ -172,6 +172,8 @@ public class JUnitTask extends Task { | |||
| private boolean includeAntRuntime = true; | |||
| private Path antRuntimeClasses = null; | |||
| private boolean showOutput = false; | |||
| /** | |||
| * Tells this task whether to smartly filter the stack frames of | |||
| * JUnit testcase errors and failures before reporting them. | |||
| @@ -467,6 +469,20 @@ public class JUnitTask extends Task { | |||
| includeAntRuntime = b; | |||
| } | |||
| /** | |||
| * Whether to send output of the testcases to Ant's logging system or not. | |||
| * | |||
| * <p>Output will always be passed to the formatters and not by | |||
| * shown by default. This option should for example be set for | |||
| * tests that are interactive and prompt the user to do | |||
| * something.</p> | |||
| * | |||
| * @since Ant 1.5 | |||
| */ | |||
| public void setShowOutput(boolean showOutput) { | |||
| this.showOutput = showOutput; | |||
| } | |||
| /** | |||
| * Creates a new JUnitRunner and enables fork of a new Java VM. | |||
| * | |||
| @@ -590,6 +606,9 @@ public class JUnitTask extends Task { | |||
| .setValue("formatter=org.apache.tools.ant.taskdefs.optional.junit.SummaryJUnitResultFormatter"); | |||
| } | |||
| cmd.createArgument().setValue("showoutput=" | |||
| + String.valueOf(showOutput)); | |||
| StringBuffer formatterArg = new StringBuffer(128); | |||
| final FormatterElement[] feArray = mergeFormatters(test); | |||
| for (int i = 0; i < feArray.length; i++) { | |||
| @@ -674,6 +693,9 @@ public class JUnitTask extends Task { | |||
| protected void handleOutput(String line) { | |||
| if (runner != null) { | |||
| runner.handleOutput(line); | |||
| if (showOutput) { | |||
| super.handleOutput(line); | |||
| } | |||
| } else { | |||
| super.handleOutput(line); | |||
| } | |||
| @@ -688,6 +710,9 @@ public class JUnitTask extends Task { | |||
| protected void handleErrorOutput(String line) { | |||
| if (runner != null) { | |||
| runner.handleErrorOutput(line); | |||
| if (showOutput) { | |||
| super.handleErrorOutput(line); | |||
| } | |||
| } else { | |||
| super.handleErrorOutput(line); | |||
| } | |||
| @@ -65,19 +65,20 @@ import junit.framework.Test; | |||
| import junit.framework.TestSuite; | |||
| import junit.framework.AssertionFailedError; | |||
| import java.lang.reflect.Method; | |||
| import java.io.BufferedReader; | |||
| import java.io.ByteArrayOutputStream; | |||
| import java.io.File; | |||
| import java.io.FileInputStream; | |||
| import java.io.IOException; | |||
| import java.io.OutputStream; | |||
| import java.io.PrintStream; | |||
| import java.io.PrintWriter; | |||
| import java.io.StringReader; | |||
| import java.io.StringWriter; | |||
| import java.io.ByteArrayOutputStream; | |||
| import java.io.IOException; | |||
| import java.io.FileInputStream; | |||
| import java.io.File; | |||
| import java.util.Enumeration; | |||
| import java.util.Hashtable; | |||
| import java.util.Properties; | |||
| import java.util.Vector; | |||
| /** | |||
| @@ -90,13 +91,15 @@ import java.util.Vector; | |||
| * public static junit.framework.Test suite() | |||
| * </code></pre> | |||
| * | |||
| * <p> If no such method exists, all public methods starting with "test" and taking no | |||
| * argument will be run. | |||
| * <p> If no such method exists, all public methods starting with | |||
| * "test" and taking no argument will be run. | |||
| * | |||
| * <p> Summary output is generated at the end. | |||
| * | |||
| * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
| * @author <a href="mailto:ehatcher@apache.org">Erik Hatcher</a> | |||
| * | |||
| * @since Ant 1.2 | |||
| */ | |||
| public class JUnitTestRunner implements TestListener { | |||
| @@ -131,6 +134,11 @@ public class JUnitTestRunner implements TestListener { | |||
| */ | |||
| private static boolean filtertrace = true; | |||
| /** | |||
| * Do we send output to System.out/.err in addition to the formatters? | |||
| */ | |||
| private boolean showOutput = false; | |||
| private static final String[] DEFAULT_TRACE_FILTERS = new String[] { | |||
| "junit.framework.TestCase", | |||
| "junit.framework.TestResult", | |||
| @@ -187,20 +195,41 @@ public class JUnitTestRunner implements TestListener { | |||
| * Constructor for fork=true or when the user hasn't specified a | |||
| * classpath. | |||
| */ | |||
| public JUnitTestRunner(JUnitTest test, boolean haltOnError, boolean filtertrace, | |||
| boolean haltOnFailure) { | |||
| this(test, haltOnError, filtertrace, haltOnFailure, null); | |||
| public JUnitTestRunner(JUnitTest test, boolean haltOnError, | |||
| boolean filtertrace, boolean haltOnFailure) { | |||
| this(test, haltOnError, filtertrace, haltOnFailure, false); | |||
| } | |||
| /** | |||
| * Constructor for fork=true or when the user hasn't specified a | |||
| * classpath. | |||
| */ | |||
| public JUnitTestRunner(JUnitTest test, boolean haltOnError, | |||
| boolean filtertrace, boolean haltOnFailure, | |||
| boolean showOutput) { | |||
| this(test, haltOnError, filtertrace, haltOnFailure, showOutput, null); | |||
| } | |||
| /** | |||
| * Constructor to use when the user has specified a classpath. | |||
| */ | |||
| public JUnitTestRunner(JUnitTest test, boolean haltOnError, boolean filtertrace, | |||
| boolean haltOnFailure, ClassLoader loader) { | |||
| public JUnitTestRunner(JUnitTest test, boolean haltOnError, | |||
| boolean filtertrace, boolean haltOnFailure, | |||
| ClassLoader loader) { | |||
| this(test, haltOnError, filtertrace, haltOnFailure, false, loader); | |||
| } | |||
| /** | |||
| * Constructor to use when the user has specified a classpath. | |||
| */ | |||
| public JUnitTestRunner(JUnitTest test, boolean haltOnError, | |||
| boolean filtertrace, boolean haltOnFailure, | |||
| boolean showOutput, ClassLoader loader) { | |||
| this.filtertrace = filtertrace; | |||
| this.junitTest = test; | |||
| this.haltOnError = haltOnError; | |||
| this.haltOnFailure = haltOnFailure; | |||
| this.showOutput = showOutput; | |||
| try { | |||
| Class testClass = null; | |||
| @@ -269,9 +298,26 @@ public class JUnitTestRunner implements TestListener { | |||
| if (forked) { | |||
| savedOut = System.out; | |||
| System.setOut(systemOut); | |||
| savedErr = System.err; | |||
| System.setErr(systemError); | |||
| if (!showOutput) { | |||
| System.setOut(systemOut); | |||
| System.setErr(systemError); | |||
| } else { | |||
| System.setOut(new PrintStream( | |||
| new TeeOutputStream( | |||
| new OutputStream[] {savedOut, | |||
| systemOut} | |||
| ) | |||
| ) | |||
| ); | |||
| System.setErr(new PrintStream( | |||
| new TeeOutputStream( | |||
| new OutputStream[] {savedErr, | |||
| systemError} | |||
| ) | |||
| ) | |||
| ); | |||
| } | |||
| } | |||
| @@ -384,13 +430,15 @@ public class JUnitTestRunner implements TestListener { | |||
| private void fireStartTestSuite() { | |||
| for (int i = 0; i < formatters.size(); i++) { | |||
| ((JUnitResultFormatter) formatters.elementAt(i)).startTestSuite(junitTest); | |||
| ((JUnitResultFormatter) formatters.elementAt(i)) | |||
| .startTestSuite(junitTest); | |||
| } | |||
| } | |||
| private void fireEndTestSuite() { | |||
| for (int i = 0; i < formatters.size(); i++) { | |||
| ((JUnitResultFormatter) formatters.elementAt(i)).endTestSuite(junitTest); | |||
| ((JUnitResultFormatter) formatters.elementAt(i)) | |||
| .endTestSuite(junitTest); | |||
| } | |||
| } | |||
| @@ -417,6 +465,9 @@ public class JUnitTestRunner implements TestListener { | |||
| * classname,filename. If filename is ommitted, System.out is | |||
| * assumed.</td><td>none</td></tr> | |||
| * | |||
| * <tr><td>showoutput</td><td>send output to System.err/.out as | |||
| * well as to the formatters?</td><td>false</td></tr> | |||
| * | |||
| * </table> | |||
| */ | |||
| public static void main(String[] args) throws IOException { | |||
| @@ -425,6 +476,7 @@ public class JUnitTestRunner implements TestListener { | |||
| boolean haltFail = false; | |||
| boolean stackfilter = true; | |||
| Properties props = new Properties(); | |||
| boolean showOut = false; | |||
| if (args.length == 0) { | |||
| System.err.println("required argument TestClassName missing"); | |||
| @@ -446,9 +498,12 @@ public class JUnitTestRunner implements TestListener { | |||
| System.exit(ERRORS); | |||
| } | |||
| } else if (args[i].startsWith("propsfile=")) { | |||
| FileInputStream in = new FileInputStream(args[i].substring(10)); | |||
| FileInputStream in = new FileInputStream(args[i] | |||
| .substring(10)); | |||
| props.load(in); | |||
| in.close(); | |||
| } else if (args[i].startsWith("showoutput=")) { | |||
| showOut = Project.toBoolean(args[i].substring(11)); | |||
| } | |||
| } | |||
| @@ -462,7 +517,8 @@ public class JUnitTestRunner implements TestListener { | |||
| } | |||
| t.setProperties(props); | |||
| JUnitTestRunner runner = new JUnitTestRunner(t, haltError, stackfilter, haltFail); | |||
| JUnitTestRunner runner = new JUnitTestRunner(t, haltError, stackfilter, | |||
| haltFail, showOut); | |||
| runner.forked = true; | |||
| transferFormatters(runner); | |||
| runner.run(); | |||
| @@ -473,7 +529,8 @@ public class JUnitTestRunner implements TestListener { | |||
| private static void transferFormatters(JUnitTestRunner runner) { | |||
| for (int i = 0; i < fromCmdLine.size(); i++) { | |||
| runner.addFormatter((JUnitResultFormatter) fromCmdLine.elementAt(i)); | |||
| runner.addFormatter((JUnitResultFormatter) fromCmdLine | |||
| .elementAt(i)); | |||
| } | |||
| } | |||
| @@ -537,4 +594,25 @@ public class JUnitTestRunner implements TestListener { | |||
| return false; | |||
| } | |||
| /** | |||
| * Helper class that sends output sent to multiple streams. | |||
| * | |||
| * @since Ant 1.5 | |||
| */ | |||
| private class TeeOutputStream extends OutputStream { | |||
| private OutputStream[] outs; | |||
| private TeeOutputStream(OutputStream[] outs) { | |||
| this.outs = outs; | |||
| } | |||
| public void write(int b) throws IOException { | |||
| for (int i = 0; i < outs.length; i++) { | |||
| outs[i].write(b); | |||
| } | |||
| } | |||
| } | |||
| } // JUnitTestRunner | |||
| @@ -89,13 +89,6 @@ | |||
| <td>Stefan, others welcome</td> | |||
| </tr> | |||
| <tr> | |||
| <td>JUnit's System.err/.out handling</td> | |||
| <td>Currently this is coupled to SummaryResultFormatter - | |||
| no SummaryFormatter, no output. Want to decouple it.</td> | |||
| <td>Stefan, others welcome</td> | |||
| </tr> | |||
| <tr> | |||
| <td>Make javadoc a real directory based task</td> | |||
| <td></td> | |||
| @@ -141,8 +134,15 @@ | |||
| <td>PGP signing task if possible</td> | |||
| <td>Not done, but deemed impossible - at least in the 1.5 | |||
| time frame.</td> | |||
| <td>Stefan, others welcome</td> | |||
| <td>Stefan</td> | |||
| </tr> | |||
| <tr> | |||
| <td>JUnit's System.err/.out handling</td> | |||
| <td>showoutput attribute has been added - doesn't work in | |||
| some cases yet (same reason as bug PR 7980)</td> | |||
| <td>Stefan</td> | |||
| </tr> | |||
| </table> | |||
| </subsection> | |||