Submitted by: Gerrit Riessen <Gerrit.Riessen@web.de> git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@269009 13f79535-47bb-0310-9956-ffa450edef68master
@@ -78,4 +78,15 @@ public interface JUnitResultFormatter extends TestListener { | |||
* Sets the stream the formatter is supposed to write its results to. | |||
*/ | |||
public void setOutput(java.io.OutputStream out); | |||
/** | |||
* This is what the test has written to System.out | |||
*/ | |||
public void setSystemOutput( String out ); | |||
/** | |||
* This is what the test has written to System.err | |||
*/ | |||
public void setSystemError( String err ); | |||
} |
@@ -66,6 +66,7 @@ import org.apache.tools.ant.types.Commandline; | |||
import org.apache.tools.ant.types.Environment; | |||
import org.apache.tools.ant.types.CommandlineJava; | |||
import org.apache.tools.ant.types.Path; | |||
import org.apache.tools.ant.types.EnumeratedAttribute; | |||
import java.io.File; | |||
@@ -88,6 +89,7 @@ import java.util.Vector; | |||
* @author Thomas Haas | |||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | |||
* @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a> | |||
* @author <a href="mailto:Gerrit.Riessen@web.de">Gerrit Riessen</a> - | |||
*/ | |||
public class JUnitTask extends Task { | |||
@@ -99,6 +101,7 @@ public class JUnitTask extends Task { | |||
private Integer timeout = null; | |||
private boolean summary = false; | |||
private String summaryValue = ""; | |||
/** | |||
* Tells this task to halt when there is an error in a test. | |||
@@ -128,6 +131,7 @@ public class JUnitTask extends Task { | |||
} | |||
} | |||
/** | |||
* Tells whether a JVM should be forked for each testcase. It avoids interference | |||
* between testcases and possibly avoids hanging the build. | |||
@@ -147,11 +151,31 @@ public class JUnitTask extends Task { | |||
/** | |||
* Tells whether the task should print a short summary of the task. | |||
* @param value <tt>true</tt> to print a summary, <tt>false</tt> otherwise. | |||
* @param value <tt>true</tt> to print a summary, | |||
* <tt>withOutAndErr</tt> to include the test's output as | |||
* well, <tt>false</tt> otherwise. | |||
* @see SummaryJUnitResultFormatter | |||
*/ | |||
public void setPrintsummary(boolean value) { | |||
summary = value; | |||
public void setPrintsummary(SummaryAttribute value) { | |||
summaryValue = value.getValue(); | |||
summary = value.asBoolean(); | |||
} | |||
/** | |||
* Print summary enumeration values. | |||
*/ | |||
public static class SummaryAttribute extends EnumeratedAttribute { | |||
public String[] getValues() { | |||
return new String[] {"true", "yes", "false", "no", | |||
"on", "off", "withOutAndErr"}; | |||
} | |||
public boolean asBoolean() { | |||
return "true".equals(value) | |||
|| "on".equals(value) | |||
|| "yes".equals(value) | |||
|| "withOutAndErr".equals(value); | |||
} | |||
} | |||
/** | |||
@@ -389,7 +413,9 @@ public class JUnitTask extends Task { | |||
if (summary) { | |||
log("Running " + test.getName(), Project.MSG_INFO); | |||
SummaryJUnitResultFormatter f = new SummaryJUnitResultFormatter(); | |||
SummaryJUnitResultFormatter f = | |||
new SummaryJUnitResultFormatter(); | |||
f.setWithOutAndErr( "withoutanderr".equalsIgnoreCase( summaryValue )); | |||
f.setOutput( getDefaultOutput() ); | |||
runner.addFormatter(f); | |||
} | |||
@@ -206,10 +206,31 @@ public class JUnitTestRunner implements TestListener { | |||
junitTest.setCounts(1, 0, 1); | |||
junitTest.setRunTime(0); | |||
} else { | |||
suite.run(res); | |||
junitTest.setCounts(res.runCount(), res.failureCount(), | |||
res.errorCount()); | |||
junitTest.setRunTime(System.currentTimeMillis() - start); | |||
PrintStream oldErr = System.err; | |||
PrintStream oldOut = System.out; | |||
ByteArrayOutputStream errStrm = new ByteArrayOutputStream(); | |||
System.setErr(new PrintStream(errStrm)); | |||
ByteArrayOutputStream outStrm = new ByteArrayOutputStream(); | |||
System.setOut(new PrintStream(outStrm)); | |||
try { | |||
suite.run(res); | |||
} finally { | |||
System.err.close(); | |||
System.out.close(); | |||
System.setErr(oldErr); | |||
System.setOut(oldOut); | |||
sendOutAndErr(new String(outStrm.toByteArray()), | |||
new String(errStrm.toByteArray())); | |||
junitTest.setCounts(res.runCount(), res.failureCount(), | |||
res.errorCount()); | |||
junitTest.setRunTime(System.currentTimeMillis() - start); | |||
} | |||
} | |||
fireEndTestSuite(); | |||
@@ -274,6 +295,16 @@ public class JUnitTestRunner implements TestListener { | |||
} | |||
} | |||
private void sendOutAndErr(String out, String err) { | |||
for (int i=0; i<formatters.size(); i++) { | |||
JUnitResultFormatter formatter = | |||
((JUnitResultFormatter)formatters.elementAt(i)); | |||
formatter.setSystemOutput(out); | |||
formatter.setSystemError(err); | |||
} | |||
} | |||
private void fireStartTestSuite() { | |||
for (int i=0; i<formatters.size(); i++) { | |||
((JUnitResultFormatter)formatters.elementAt(i)).startTestSuite(junitTest); | |||
@@ -96,6 +96,9 @@ public class PlainJUnitResultFormatter implements JUnitResultFormatter { | |||
*/ | |||
private boolean failed = true; | |||
private String systemOutput = null; | |||
private String systemError = null; | |||
public PlainJUnitResultFormatter() { | |||
inner = new StringWriter(); | |||
wri = new PrintWriter(inner); | |||
@@ -105,6 +108,14 @@ public class PlainJUnitResultFormatter implements JUnitResultFormatter { | |||
this.out = out; | |||
} | |||
public void setSystemOutput(String out) { | |||
systemOutput = out; | |||
} | |||
public void setSystemError(String err) { | |||
systemError = err; | |||
} | |||
/** | |||
* Empty. | |||
*/ | |||
@@ -115,9 +126,10 @@ public class PlainJUnitResultFormatter implements JUnitResultFormatter { | |||
* The whole testsuite ended. | |||
*/ | |||
public void endTestSuite(JUnitTest suite) throws BuildException { | |||
String newLine = System.getProperty("line.separator"); | |||
StringBuffer sb = new StringBuffer("Testsuite: "); | |||
sb.append(suite.getName()); | |||
sb.append(System.getProperty("line.separator")); | |||
sb.append(newLine); | |||
sb.append("Tests run: "); | |||
sb.append(suite.runCount()); | |||
sb.append(", Failures: "); | |||
@@ -127,8 +139,25 @@ public class PlainJUnitResultFormatter implements JUnitResultFormatter { | |||
sb.append(", Time elapsed: "); | |||
sb.append(nf.format(suite.getRunTime()/1000.0)); | |||
sb.append(" sec"); | |||
sb.append(System.getProperty("line.separator")); | |||
sb.append(System.getProperty("line.separator")); | |||
sb.append(newLine); | |||
sb.append(newLine); | |||
// append the err and output streams to the log | |||
if (systemOutput != null && systemOutput.length() > 0) { | |||
sb.append("------------- Standard Output ---------------" ) | |||
.append(newLine) | |||
.append(systemOutput) | |||
.append("------------- ---------------- ---------------" ) | |||
.append(newLine); | |||
} | |||
if (systemError != null && systemError.length() > 0) { | |||
sb.append("------------- Standard Error -----------------" ) | |||
.append(newLine) | |||
.append(systemError) | |||
.append("------------- ---------------- ---------------" ) | |||
.append(newLine); | |||
} | |||
if (out != null) { | |||
try { | |||
@@ -79,6 +79,10 @@ public class SummaryJUnitResultFormatter implements JUnitResultFormatter { | |||
*/ | |||
private OutputStream out; | |||
private boolean withOutAndErr = false; | |||
private String systemOutput = null; | |||
private String systemError = null; | |||
/** | |||
* Empty | |||
*/ | |||
@@ -116,10 +120,27 @@ public class SummaryJUnitResultFormatter implements JUnitResultFormatter { | |||
this.out = out; | |||
} | |||
public void setSystemOutput( String out ) { | |||
systemOutput = out; | |||
} | |||
public void setSystemError( String err ) { | |||
systemError = err; | |||
} | |||
/** | |||
* Should the output to System.out and System.err be written to | |||
* the summary. | |||
*/ | |||
public void setWithOutAndErr( boolean value ) { | |||
withOutAndErr = value; | |||
} | |||
/** | |||
* The whole testsuite ended. | |||
*/ | |||
public void endTestSuite(JUnitTest suite) throws BuildException { | |||
String newLine = System.getProperty("line.separator"); | |||
StringBuffer sb = new StringBuffer("Tests run: "); | |||
sb.append(suite.runCount()); | |||
sb.append(", Failures: "); | |||
@@ -129,7 +150,20 @@ public class SummaryJUnitResultFormatter implements JUnitResultFormatter { | |||
sb.append(", Time elapsed: "); | |||
sb.append(nf.format(suite.getRunTime()/1000.0)); | |||
sb.append(" sec"); | |||
sb.append(System.getProperty("line.separator")); | |||
sb.append(newLine); | |||
if (withOutAndErr) { | |||
if (systemOutput != null && systemOutput.length() > 0) { | |||
sb.append( "Output:" ).append(newLine).append(systemOutput) | |||
.append(newLine); | |||
} | |||
if (systemError != null && systemError.length() > 0) { | |||
sb.append( "Error: " ).append(newLine).append(systemError) | |||
.append(newLine); | |||
} | |||
} | |||
try { | |||
out.write(sb.toString().getBytes()); | |||
out.flush(); | |||
@@ -80,6 +80,12 @@ public interface XMLConstants { | |||
/** the failure element */ | |||
public final static String FAILURE = "failure"; | |||
/** the system-err element */ | |||
public final static String SYSTEM_ERR = "system-err"; | |||
/** the system-out element */ | |||
public final static String SYSTEM_OUT = "system-out"; | |||
/** package attribute for the aggregate document */ | |||
public final static String ATTR_PACKAGE = "package"; | |||
@@ -117,6 +117,14 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstan | |||
this.out = out; | |||
} | |||
public void setSystemOutput(String out) { | |||
formatOutput(SYSTEM_OUT, out); | |||
} | |||
public void setSystemError(String out) { | |||
formatOutput(SYSTEM_ERR, out); | |||
} | |||
/** | |||
* The whole testsuite started. | |||
*/ | |||
@@ -230,4 +238,11 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstan | |||
nested.appendChild(trace); | |||
} | |||
private void formatOutput(String type, String output) { | |||
Element nested = doc.createElement(type); | |||
rootElement.appendChild(nested); | |||
Text content = doc.createTextNode(output); | |||
nested.appendChild(content); | |||
} | |||
} // XMLJUnitResultFormatter |