ASF Bugzilla – Attachment 14963 Details for
Bug 34748
[PATCH] JUnit Task enhancement to allow a single test method to be specified
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
[PATCH] JUnit - add ability to execute a single test method
ant.patch (text/plain), 17.84 KB, created by
John Sisson
on 2005-05-08 06:25:18 UTC
(
hide
)
Description:
[PATCH] JUnit - add ability to execute a single test method
Filename:
MIME Type:
Creator:
John Sisson
Created:
2005-05-08 06:25:18 UTC
Size:
17.84 KB
patch
obsolete
>? 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 @@ > <td align="center">Yes</td> > </tr> > <tr> >+ <td valign="top">method</td> >+ <td valign="top">Name of a single test case method to execute. <em>Since Ant 1.7</em><P> >+ The <code>method</code> attribute can be useful in the following scenarios: >+ <UL> >+ <LI>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. >+ </LI> >+ <LI>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). >+ </LI> >+ </UL> >+ </td> >+ <td align="center">No</td> >+ </tr> >+ <tr> > <td valign="top">fork</td> > <td valign="top">Run the tests in a separate VM. > Overrides value set in <code><junit></code>.</td> >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 @@ > * <tr><td>logtestlistenerevents</td><td>log TestListener events to > * System.out.</td><td>false</td></tr> > * >+ * <tr><td>method</td><td>The name of an individual test method >+ * to execute. >+ * </td><td>null</td></tr> >+ * > * </table> > */ > 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);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 34748
:
14935
| 14963