? bin
Index: docs/manual/OptionalTasks/junit.html
===================================================================
RCS file: /home/cvspublic/ant/docs/manual/OptionalTasks/junit.html,v
retrieving revision 1.40
diff -u -r1.40 junit.html
--- docs/manual/OptionalTasks/junit.html 29 Apr 2005 18:58:09 -0000 1.40
+++ docs/manual/OptionalTasks/junit.html 6 May 2005 00:23:43 -0000
@@ -378,6 +378,23 @@
Yes |
+ method |
+ Name of a single test case method to execute. Since Ant 1.7
+ The method attribute can be useful in the following scenarios:
+
+ - A test method has failed and you want to re-run the test method to test a fix
+ or re-run the test under the Java debugger without having to wait for the other
+ (possibly long running) test methods to complete.
+
+ - A test method is running slower than expected and you want to re-run
+ the slow test method under a Java profiler (without the overhead of
+ running the profiler whilst other test methods are being executed).
+
+
+ |
+ No |
+
+
fork |
Run the tests in a separate VM.
Overrides value set in <junit> . |
Index: src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
===================================================================
RCS file: /home/cvspublic/ant/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java,v
retrieving revision 1.117
diff -u -r1.117 JUnitTask.java
--- src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java 30 Mar 2005 17:06:39 -0000 1.117
+++ src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java 8 May 2005 03:47:49 -0000
@@ -802,6 +802,9 @@
cmd.createArgument().setValue("haltOnError=" + test.getHaltonerror());
cmd.createArgument().setValue("haltOnFailure="
+ test.getHaltonfailure());
+ cmd.createArgument().setValue("method=" +
+ ( (test.getMethod() != null) ? test.getMethod() : "" ) );
+
if (includeAntRuntime) {
Vector v = Execute.getProcEnvironment();
Enumeration e = v.elements();
@@ -821,6 +824,7 @@
}
if (summary) {
+ // TODO should we log a different message here if test.getMethod() != null ?
log("Running " + test.getName(), Project.MSG_INFO);
String prefix = "";
if ("withoutanderr".equalsIgnoreCase(summaryValue)) {
@@ -1069,11 +1073,15 @@
if (classLoader != null) {
classLoader.setThreadContextLoader();
}
- runner = new JUnitTestRunner(test, test.getHaltonerror(),
+ runner = new JUnitTestRunner(test,
+ test.getMethod(),
+ test.getHaltonerror(),
test.getFiltertrace(),
test.getHaltonfailure(), false,
- true, classLoader);
+ true,
+ classLoader);
if (summary) {
+ // TODO should we log a different message here if test.getMethod() != null ?
log("Running " + test.getName(), Project.MSG_INFO);
SummaryJUnitResultFormatter f =
Index: src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java
===================================================================
RCS file: /home/cvspublic/ant/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java,v
retrieving revision 1.23
diff -u -r1.23 JUnitTest.java
--- src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java 9 Mar 2004 16:48:31 -0000 1.23
+++ src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTest.java 6 May 2005 05:33:55 -0000
@@ -39,6 +39,9 @@
/** the name of the test case */
private String name = null;
+ /** the name of a test method to execute */
+ private String method = null;
+
/** the name of the result file */
private String outfile = null;
@@ -59,11 +62,24 @@
}
public JUnitTest(String name, boolean haltOnError, boolean haltOnFailure,
- boolean filtertrace) {
+ boolean filtertrace) {
+ this(name, haltOnError, haltOnFailure, filtertrace, null);
+ }
+
+ public JUnitTest(String name, boolean haltOnError, boolean haltOnFailure,
+ boolean filtertrace, String method) {
this.name = name;
this.haltOnError = haltOnError;
this.haltOnFail = haltOnFailure;
this.filtertrace = filtertrace;
+ this.method = method;
+ }
+
+ /**
+ * Set the name of the individual test method to be invoked.
+ */
+ public void setMethod(String value) {
+ method = value;
}
/**
@@ -81,6 +97,15 @@
}
/**
+ * Get the name of the individual test method to be invoked.
+ *
+ * @return the name of the individual test method to be invoked.
+ */
+ public String getMethod() {
+ return method;
+ }
+
+ /**
* Get the name of the test class.
*/
public String getName() {
Index: src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java
===================================================================
RCS file: /home/cvspublic/ant/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java,v
retrieving revision 1.58
diff -u -r1.58 JUnitTestRunner.java
--- src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java 30 Mar 2005 17:08:27 -0000 1.58
+++ src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunner.java 8 May 2005 01:27:06 -0000
@@ -165,6 +165,9 @@
/** Do we print TestListener events? */
private boolean logTestListenerEvents = false;
+ /** Name of single test method to execute */
+ private String method = null;
+
/**
* Constructor for fork=true or when the user hasn't specified a
* classpath.
@@ -192,11 +195,23 @@
public JUnitTestRunner(JUnitTest test, boolean haltOnError,
boolean filtertrace, boolean haltOnFailure,
boolean showOutput, boolean logTestListenerEvents) {
- this(test, haltOnError, filtertrace, haltOnFailure, showOutput,
+ this(test, null, haltOnError, filtertrace, haltOnFailure, showOutput,
logTestListenerEvents, null);
}
/**
+ * Constructor for fork=true or when the user hasn't specified a
+ * classpath.
+ * @since Ant 1.7
+ */
+ public JUnitTestRunner(JUnitTest test, String method, boolean haltOnError,
+ boolean filtertrace, boolean haltOnFailure,
+ boolean showOutput, boolean logTestListenerEvents) {
+ this(test, method, haltOnError, filtertrace, haltOnFailure, showOutput,
+ logTestListenerEvents, null);
+ }
+
+ /**
* Constructor to use when the user has specified a classpath.
*/
public JUnitTestRunner(JUnitTest test, boolean haltOnError,
@@ -223,12 +238,26 @@
boolean filtertrace, boolean haltOnFailure,
boolean showOutput, boolean logTestListenerEvents,
ClassLoader loader) {
+ this(test, null, haltOnError, filtertrace, haltOnFailure, showOutput,
+ logTestListenerEvents, loader);
+ }
+
+
+ /**
+ * Constructor to use when the user has specified a classpath.
+ * @since Ant 1.7
+ */
+ public JUnitTestRunner(JUnitTest test, String method, 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.method = method;
this.loader = loader;
}
@@ -288,25 +317,35 @@
}
Method suiteMethod = null;
- try {
- // check if there is a suite method
- suiteMethod = testClass.getMethod("suite", new Class[0]);
- } catch (NoSuchMethodException e) {
- // no appropriate suite method found. We don't report any
- // error here since it might be perfectly normal.
+ if (method != null && method.length() > 0)
+ {
+ // we are invoking a specific test method
+ // ensure ERROR is generated in catch block if method doesn't exist
+ testClass.getMethod(method, new Class[0]); // throws NoSuchMethodException
+ suite = TestSuite.createTest(testClass, method);
}
- if (suiteMethod != null) {
- // if there is a suite method available, then try
- // to extract the suite from it. If there is an error
- // here it will be caught below and reported.
- suite = (Test) suiteMethod.invoke(null, new Class[0]);
- } else {
- // try to extract a test suite automatically this
- // will generate warnings if the class is no
- // suitable Test
- suite = new TestSuite(testClass);
+ else
+ {
+ try {
+ // check if there is a suite method
+ suiteMethod = testClass.getMethod("suite", new Class[0]);
+ } catch (NoSuchMethodException e) {
+ // no appropriate suite method found. We don't report any
+ // error here since it might be perfectly normal.
+ }
+
+ if (suiteMethod != null) {
+ // if there is a suite method available, then try
+ // to extract the suite from it. If there is an error
+ // here it will be caught below and reported.
+ suite = (Test) suiteMethod.invoke(null, new Class[0]);
+ } else {
+ // try to extract a test suite automatically this
+ // will generate warnings if the class is no
+ // suitable Test
+ suite = new TestSuite(testClass);
+ }
}
-
} catch (Throwable e) {
retCode = ERRORS;
exception = e;
@@ -530,6 +569,10 @@
*
logtestlistenerevents | log TestListener events to
* System.out. | false |
*
+ * method | The name of an individual test method
+ * to execute.
+ * | null |
+ *
*
*/
public static void main(String[] args) throws IOException {
@@ -540,6 +583,7 @@
boolean showOut = false;
boolean logTestListenerEvents = false;
String noCrashFile = null;
+ String method = null;
if (args.length == 0) {
System.err.println("required argument TestClassName missing");
@@ -576,6 +620,8 @@
showOut = Project.toBoolean(args[i].substring(11));
} else if (args[i].startsWith("logtestlistenerevents=")) {
logTestListenerEvents = Project.toBoolean(args[i].substring(22));
+ } else if (args[i].startsWith("method=")) {
+ method = args[i].substring(7);
}
}
@@ -602,7 +648,7 @@
JUnitTest t = new JUnitTest(testCaseName);
t.setTodir(new File(st.nextToken()));
t.setOutfile(st.nextToken());
- code = launch(t, haltError, stackfilter, haltFail,
+ code = launch(t, null, haltError, stackfilter, haltFail,
showOut, logTestListenerEvents, props);
errorOccurred = (code == ERRORS);
failureOccurred = (code != SUCCESS);
@@ -624,7 +670,7 @@
e.printStackTrace();
}
} else {
- returnCode = launch(new JUnitTest(args[0]), haltError,
+ returnCode = launch(new JUnitTest(args[0]), method, haltError,
stackfilter, haltFail, showOut,
logTestListenerEvents, props);
}
@@ -722,14 +768,14 @@
/**
* @since Ant 1.6.2
*/
- private static int launch(JUnitTest t, boolean haltError,
+ private static int launch(JUnitTest t, String method, boolean haltError,
boolean stackfilter, boolean haltFail,
boolean showOut, boolean logTestListenerEvents,
Properties props) {
t.setProperties(props);
JUnitTestRunner runner =
- new JUnitTestRunner(t, haltError, stackfilter, haltFail, showOut,
- logTestListenerEvents);
+ new JUnitTestRunner(t, method, haltError, stackfilter, haltFail,
+ showOut, logTestListenerEvents);
runner.forked = true;
transferFormatters(runner, t);
Index: src/testcases/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunnerTest.java
===================================================================
RCS file: /home/cvspublic/ant/src/testcases/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunnerTest.java,v
retrieving revision 1.10
diff -u -r1.10 JUnitTestRunnerTest.java
--- src/testcases/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunnerTest.java 9 Mar 2004 16:49:02 -0000 1.10
+++ src/testcases/org/apache/tools/ant/taskdefs/optional/junit/JUnitTestRunnerTest.java 7 May 2005 12:48:25 -0000
@@ -18,6 +18,7 @@
import java.io.*;
import junit.framework.*;
+
import org.apache.tools.ant.BuildException;
/**
@@ -32,6 +33,21 @@
super(name);
}
+ // check that a valid method name generates no errors
+ public void testValidMethod(){
+ TestRunner runner = createRunnerForTestMethod(ValidMethodTestCase.class,"testA");
+ runner.run();
+ assertEquals(runner.getFormatter().getError(), JUnitTestRunner.SUCCESS, runner.getRetCode());
+ }
+
+ // check that having an invalid method name generates an error
+ public void testInvalidMethod(){
+ TestRunner runner = createRunnerForTestMethod(InvalidMethodTestCase.class,"testInvalid");
+ runner.run();
+ String error = runner.getFormatter().getError();
+ assertEquals(error, JUnitTestRunner.ERRORS, runner.getRetCode());
+ }
+
// check that having no suite generates no errors
public void testNoSuite(){
TestRunner runner = createRunner(NoSuiteTestCase.class);
@@ -74,14 +90,22 @@
}
protected TestRunner createRunner(Class clazz){
- return new TestRunner(new JUnitTest(clazz.getName()), true, true, true);
+ return new TestRunner(new JUnitTest(clazz.getName()), null,
+ true, true, true);
}
+ protected TestRunner createRunnerForTestMethod(Class clazz, String method){
+ return new TestRunner(new JUnitTest(clazz.getName()), method,
+ true, true, true);
+ }
+
// the test runner that wrap the dummy formatter that interests us
private final static class TestRunner extends JUnitTestRunner {
private ResultFormatter formatter = new ResultFormatter();
- TestRunner(JUnitTest test, boolean haltonerror, boolean filtertrace, boolean haltonfailure){
- super(test, haltonerror, filtertrace, haltonfailure, TestRunner.class.getClassLoader());
+ TestRunner(JUnitTest test, String method, boolean haltonerror,
+ boolean filtertrace, boolean haltonfailure){
+ super(test, method, haltonerror, filtertrace, haltonfailure,
+ false, false, TestRunner.class.getClassLoader());
// use the classloader that loaded this class otherwise
// it will not be able to run inner classes if this test
// is ran in non-forked mode.
@@ -120,6 +144,24 @@
public static class NoTestCase {
}
+ public static class InvalidMethodTestCase extends TestCase {
+ public InvalidMethodTestCase(String name){ super(name); }
+ public void testA(){
+ throw new NullPointerException("thrown on purpose");
+ }
+ }
+
+ public static class ValidMethodTestCase extends TestCase {
+ public ValidMethodTestCase(String name){ super(name); }
+ public void testA(){
+ // expected to be executed
+ }
+ public void testB(){
+ // should not be executed
+ throw new NullPointerException("thrown on purpose");
+ }
+ }
+
public static class InvalidTestCase extends TestCase {
public InvalidTestCase(String name){
super(name);