Browse Source

#31885: <junit> logs more detailed events for individual tests it is running.

git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@278072 13f79535-47bb-0310-9956-ffa450edef68
master
Jesse N. Glick 20 years ago
parent
commit
a898d14776
3 changed files with 191 additions and 16 deletions
  1. +47
    -9
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
  2. +65
    -7
      src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java
  3. +79
    -0
      src/testcases/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestListenerTest.java

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

@@ -34,6 +34,9 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Vector;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestResult;
import org.apache.tools.ant.AntClassLoader;
import org.apache.tools.ant.BuildException;
import org.apache.tools.ant.Project;
@@ -41,7 +44,6 @@ import org.apache.tools.ant.Task;
import org.apache.tools.ant.taskdefs.Execute;
import org.apache.tools.ant.taskdefs.ExecuteWatchdog;
import org.apache.tools.ant.taskdefs.LogOutputStream;
import org.apache.tools.ant.taskdefs.LogStreamHandler;
import org.apache.tools.ant.types.Assertions;
import org.apache.tools.ant.types.Commandline;
import org.apache.tools.ant.types.CommandlineJava;
@@ -52,9 +54,7 @@ import org.apache.tools.ant.types.Permissions;
import org.apache.tools.ant.types.PropertySet;
import org.apache.tools.ant.util.FileUtils;
import org.apache.tools.ant.util.LoaderUtils;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
import junit.framework.TestResult;
import org.apache.tools.ant.taskdefs.PumpStreamHandler;

/**
* Runs JUnit tests.
@@ -149,6 +149,11 @@ public class JUnitTask extends Task {
private ForkMode forkMode = new ForkMode("perTest");

private static final int STRING_BUFFER_SIZE = 128;
/**
* @since Ant 1.7
*/
public static final String TESTLISTENER_PREFIX =
"junit.framework.TestListener: ";

private static final FileUtils FILE_UTILS = FileUtils.getFileUtils();

@@ -829,6 +834,7 @@ public class JUnitTask extends Task {

cmd.createArgument().setValue("showoutput="
+ String.valueOf(showOutput));
cmd.createArgument().setValue("logtestlistenerevents=true"); // #31885

StringBuffer formatterArg = new StringBuffer(STRING_BUFFER_SIZE);
final FormatterElement[] feArray = mergeFormatters(test);
@@ -871,9 +877,9 @@ public class JUnitTask extends Task {
+ "file.", e, getLocation());
}

Execute execute = new Execute(new LogStreamHandler(this,
Project.MSG_INFO,
Project.MSG_WARN),
Execute execute = new Execute(new JUnitLogStreamHandler(this,
Project.MSG_INFO,
Project.MSG_WARN),
watchdog);
execute.setCommandline(cmd.getCommandline());
execute.setAntRun(getProject());
@@ -941,7 +947,9 @@ public class JUnitTask extends Task {
* @since Ant 1.5
*/
protected void handleOutput(String output) {
if (runner != null) {
if (output.startsWith(TESTLISTENER_PREFIX))
log(output, Project.MSG_VERBOSE);
else if (runner != null) {
runner.handleOutput(output);
if (showOutput) {
super.handleOutput(output);
@@ -1063,7 +1071,8 @@ public class JUnitTask extends Task {
}
runner = new JUnitTestRunner(test, test.getHaltonerror(),
test.getFiltertrace(),
test.getHaltonfailure(), classLoader);
test.getHaltonfailure(), false,
true, classLoader);
if (summary) {
log("Running " + test.getName(), Project.MSG_INFO);

@@ -1549,4 +1558,33 @@ public class JUnitTask extends Task {
public boolean timedOut = false;
public boolean crashed = false;
}

/**
* @since Ant 1.7
*/
protected static class JUnitLogOutputStream extends LogOutputStream {
private Task task; // local copy since LogOutputStream.task is private
public JUnitLogOutputStream(Task task, int level) {
super(task, level);
this.task = task;
}
protected void processLine(String line, int level) {
if (line.startsWith(TESTLISTENER_PREFIX))
task.log(line, Project.MSG_VERBOSE);
else
super.processLine(line, level);
}
}

/**
* @since Ant 1.7
*/
protected static class JUnitLogStreamHandler extends PumpStreamHandler {
public JUnitLogStreamHandler(Task task, int outlevel, int errlevel) {
super(new JUnitLogOutputStream(task, outlevel),
new LogOutputStream(task, errlevel));
}
}
}

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

@@ -161,6 +161,9 @@ public class JUnitTestRunner implements TestListener {

/** ClassLoader passed in in non-forked mode. */
private ClassLoader loader;
/** Do we print TestListener events? */
private boolean logTestListenerEvents = false;

/**
* Constructor for fork=true or when the user hasn't specified a
@@ -178,7 +181,19 @@ public class JUnitTestRunner implements TestListener {
public JUnitTestRunner(JUnitTest test, boolean haltOnError,
boolean filtertrace, boolean haltOnFailure,
boolean showOutput) {
this(test, haltOnError, filtertrace, haltOnFailure, showOutput, null);
this(test, haltOnError, filtertrace, haltOnFailure, showOutput, false);
}

/**
* Constructor for fork=true or when the user hasn't specified a
* classpath.
* @since Ant 1.7
*/
public JUnitTestRunner(JUnitTest test, boolean haltOnError,
boolean filtertrace, boolean haltOnFailure,
boolean showOutput, boolean logTestListenerEvents) {
this(test, haltOnError, filtertrace, haltOnFailure, showOutput,
logTestListenerEvents, null);
}

/**
@@ -196,14 +211,29 @@ public class JUnitTestRunner implements TestListener {
public JUnitTestRunner(JUnitTest test, boolean haltOnError,
boolean filtertrace, boolean haltOnFailure,
boolean showOutput, ClassLoader loader) {
this(test, haltOnError, filtertrace, haltOnFailure, showOutput,
false, loader);
}

/**
* Constructor to use when the user has specified a classpath.
* @since Ant 1.7
*/
public JUnitTestRunner(JUnitTest test, boolean haltOnError,
boolean filtertrace, boolean haltOnFailure,
boolean showOutput, boolean logTestListenerEvents,
ClassLoader loader) {
JUnitTestRunner.filtertrace = filtertrace;
this.junitTest = test;
this.haltOnError = haltOnError;
this.haltOnFailure = haltOnFailure;
this.showOutput = showOutput;
this.logTestListenerEvents = logTestListenerEvents;
this.loader = loader;
}

private PrintStream savedOut = null;
public void run() {
res = new TestResult();
res.addListener(this);
@@ -217,7 +247,6 @@ public class JUnitTestRunner implements TestListener {
ByteArrayOutputStream outStrm = new ByteArrayOutputStream();
systemOut = new PrintStream(outStrm);

PrintStream savedOut = null;
PrintStream savedErr = null;

if (forked) {
@@ -295,6 +324,7 @@ public class JUnitTestRunner implements TestListener {
junitTest.setRunTime(0);
} else {
try {
logTestListenerEvent("tests to run: " + suite.countTestCases());
suite.run(res);
} finally {
junitTest.setCounts(res.runCount(), res.failureCount(),
@@ -344,6 +374,8 @@ public class JUnitTestRunner implements TestListener {
* <p>A new Test is started.
*/
public void startTest(Test t) {
String testName = JUnitVersionHelper.getTestCaseName(t);
logTestListenerEvent("startTest(" + testName + ")");
}

/**
@@ -352,6 +384,17 @@ public class JUnitTestRunner implements TestListener {
* <p>A Test is finished.
*/
public void endTest(Test test) {
String testName = JUnitVersionHelper.getTestCaseName(test);
logTestListenerEvent("endTest(" + testName + ")");
}
private void logTestListenerEvent(String msg) {
PrintStream out = forked ? savedOut : System.out;
if (logTestListenerEvents) {
out.flush();
out.println(JUnitTask.TESTLISTENER_PREFIX + msg);
out.flush();
}
}

/**
@@ -360,6 +403,8 @@ public class JUnitTestRunner implements TestListener {
* <p>A Test failed.
*/
public void addFailure(Test test, Throwable t) {
String testName = JUnitVersionHelper.getTestCaseName(test);
logTestListenerEvent("addFailure(" + testName + ", " + t.getMessage() + ")");
if (haltOnFailure) {
res.stop();
}
@@ -380,6 +425,8 @@ public class JUnitTestRunner implements TestListener {
* <p>An error occurred while running the test.
*/
public void addError(Test test, Throwable t) {
String testName = JUnitVersionHelper.getTestCaseName(test);
logTestListenerEvent("addError(" + testName + ", " + t.getMessage() + ")");
if (haltOnError) {
res.stop();
}
@@ -395,7 +442,9 @@ public class JUnitTestRunner implements TestListener {
}

protected void handleOutput(String output) {
if (systemOut != null) {
if (!logTestListenerEvents && output.startsWith(JUnitTask.TESTLISTENER_PREFIX))
; // ignore
else if (systemOut != null) {
systemOut.print(output);
}
}
@@ -478,6 +527,9 @@ public class JUnitTestRunner implements TestListener {
* <tr><td>showoutput</td><td>send output to System.err/.out as
* well as to the formatters?</td><td>false</td></tr>
*
* <tr><td>logtestlistenerevents</td><td>log TestListener events to
* System.out.</td><td>false</td></tr>
*
* </table>
*/
public static void main(String[] args) throws IOException {
@@ -486,6 +538,7 @@ public class JUnitTestRunner implements TestListener {
boolean stackfilter = true;
Properties props = new Properties();
boolean showOut = false;
boolean logTestListenerEvents = false;
String noCrashFile = null;

if (args.length == 0) {
@@ -521,6 +574,8 @@ public class JUnitTestRunner implements TestListener {
in.close();
} else if (args[i].startsWith("showoutput=")) {
showOut = Project.toBoolean(args[i].substring(11));
} else if (args[i].startsWith("logtestlistenerevents=")) {
logTestListenerEvents = Project.toBoolean(args[i].substring(22));
}
}

@@ -548,7 +603,7 @@ public class JUnitTestRunner implements TestListener {
t.setTodir(new File(st.nextToken()));
t.setOutfile(st.nextToken());
code = launch(t, haltError, stackfilter, haltFail,
showOut, props);
showOut, logTestListenerEvents, props);
errorOccured = (code == ERRORS);
failureOccured = (code != SUCCESS);
if (errorOccured || failureOccured) {
@@ -570,7 +625,8 @@ public class JUnitTestRunner implements TestListener {
}
} else {
returnCode = launch(new JUnitTest(args[0]), haltError,
stackfilter, haltFail, showOut, props);
stackfilter, haltFail, showOut,
logTestListenerEvents, props);
}

registerNonCrash(noCrashFile);
@@ -668,10 +724,12 @@ public class JUnitTestRunner implements TestListener {
*/
private static int launch(JUnitTest t, boolean haltError,
boolean stackfilter, boolean haltFail,
boolean showOut, Properties props) {
boolean showOut, boolean logTestListenerEvents,
Properties props) {
t.setProperties(props);
JUnitTestRunner runner =
new JUnitTestRunner(t, haltError, stackfilter, haltFail, showOut);
new JUnitTestRunner(t, haltError, stackfilter, haltFail, showOut,
logTestListenerEvents);
runner.forked = true;
transferFormatters(runner, t);



+ 79
- 0
src/testcases/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestListenerTest.java View File

@@ -0,0 +1,79 @@
/*
* Copyright 2005 The Apache Software Foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/

package org.apache.tools.ant.taskdefs.optional.junit;

import org.apache.tools.ant.BuildFileTest;

public class JUnitTestListenerTest extends BuildFileTest {

// The captureToSummary test writes to stdout and stderr, good for
// verifying that the TestListener support doesn't break anything.
private static final String PASS_TEST_TARGET = "captureToSummary";

// testNoCrash is the test invoked by the captureToSummary's junit task
private static final String PASS_TEST = "testNoCrash";

public JUnitTestListenerTest(String name) {
super(name);
}

public void setUp() {
configureProject("src/etc/testcases/taskdefs/optional/junit.xml");
}

public void testFullLogOutput() {
executeTarget(PASS_TEST_TARGET);
assertTrue("expecting full log to have BuildListener events",
hasBuildListenerEvents(getFullLog()));
}
public void testNoLogOutput() {
executeTarget(PASS_TEST_TARGET);
assertFalse("expecting log to not have BuildListener events",
hasBuildListenerEvents(getLog()));
}

public void testTestCountFired() {
executeTarget(PASS_TEST_TARGET);
assertTrue("expecting test count message",
hasEventMessage(JUnitTask.TESTLISTENER_PREFIX +
"tests to run: "));
}
public void testStartTestFired() {
executeTarget(PASS_TEST_TARGET);
assertTrue("expecting test started message",
hasEventMessage(JUnitTask.TESTLISTENER_PREFIX +
"startTest(" + PASS_TEST + ")"));
}
public void testEndTestFired() {
executeTarget(PASS_TEST_TARGET);
assertTrue("expecting test ended message",
hasEventMessage(JUnitTask.TESTLISTENER_PREFIX +
"endTest(" + PASS_TEST + ")"));
}
private boolean hasBuildListenerEvents(String log) {
return log.indexOf(JUnitTask.TESTLISTENER_PREFIX) >= 0;
}

private boolean hasEventMessage(String eventPrefix) {
return getFullLog().indexOf(eventPrefix) >= 0;
}
}

Loading…
Cancel
Save