Browse Source

Add new showoutput attribute to <junit>.

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-ffa450edef68
master
Stefan Bodewig 23 years ago
parent
commit
e7de779f7c
7 changed files with 177 additions and 57 deletions
  1. +9
    -4
      WHATSNEW
  2. +22
    -22
      docs/ant15_todo.html
  3. +7
    -0
      docs/manual/OptionalTasks/junit.html
  4. +9
    -4
      src/etc/testcases/taskdefs/optional/junit.xml
  5. +25
    -0
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
  6. +97
    -19
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java
  7. +8
    -8
      xdocs/ant15_todo.xml

+ 9
- 4
WHATSNEW View File

@@ -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
===========================================



+ 22
- 22
docs/ant15_todo.html View File

@@ -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>


+ 7
- 0
docs/manual/OptionalTasks/junit.html View File

@@ -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>


+ 9
- 4
src/etc/testcases/taskdefs/optional/junit.xml View File

@@ -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>


+ 25
- 0
src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java View File

@@ -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);
}


+ 97
- 19
src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java View File

@@ -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

+ 8
- 8
xdocs/ant15_todo.xml View File

@@ -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>



Loading…
Cancel
Save