Author: jhm
Date: Mon Aug  6 00:55:07 2007
New Revision: 563053

URL: http://svn.apache.org/viewvc?view=rev&rev=563053
Log:
New JUnit formatter: collects failing test cases (testXXX methods) for a rerun.
* works from command line
* its own JUnit test scenario fails (for - to me - unknown reason)

* BFT has new method 'assertOutputNotContaining' similar to 
'assertOutputContaining'


Added:
    
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java
Modified:
    ant/core/trunk/src/etc/testcases/taskdefs/optional/junit.xml
    
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java
    
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
    ant/core/trunk/src/tests/junit/org/apache/tools/ant/BuildFileTest.java
    
ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java

Modified: ant/core/trunk/src/etc/testcases/taskdefs/optional/junit.xml
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/etc/testcases/taskdefs/optional/junit.xml?view=diff&rev=563053&r1=563052&r2=563053
==============================================================================
--- ant/core/trunk/src/etc/testcases/taskdefs/optional/junit.xml (original)
+++ ant/core/trunk/src/etc/testcases/taskdefs/optional/junit.xml Mon Aug  6 
00:55:07 2007
@@ -143,4 +143,94 @@
       </batchtest>
     </junit>
   </target>
+
+  <target name="failureRecorder.prepare">
+    <property name="tmp.dir" value="out"/>
+    <mkdir dir="${tmp.dir}/org"/>
+    <echo file="${tmp.dir}/A.java">
+        import junit.framework.*;
+        public class A extends TestCase {
+            public A(String s) { super(s); }
+            public void test01() { System.out.println("A.test01"); }
+            public void test02() { System.out.println("A.test02"); fail(); }
+            public void test03() { System.out.println("A.test03"); fail(); }
+      }
+    </echo>
+    <echo file="${tmp.dir}/B.java">
+        import junit.framework.*;
+        public class B extends TestCase {
+            public B(String s) { super(s); }
+            public void test04() { System.out.println("B.test04"); fail(); }
+            public void test05() { System.out.println("B.test05"); }
+            public void test06() { System.out.println("B.test06"); }
+        }
+    </echo>
+    <echo file="${tmp.dir}/C.java">
+        import junit.framework.*;
+        public class C extends TestCase {
+            public C(String s) { super(s); }
+            public void test07() { System.out.println("C.test07"); }
+            public void test08() { System.out.println("C.test08"); }
+            public void test09() { System.out.println("C.test09"); }
+        }
+    </echo>
+    <echo file="${tmp.dir}/org/D.java">
+       package org;
+        import junit.framework.*;
+        public class D extends TestCase {
+            public D(String s) { super(s); }
+            public void test10() { System.out.println("D.test10"); fail(); }
+        }
+    </echo>
+    <javac srcdir="${tmp.dir}" destdir="${tmp.dir}"/>
+  </target>
+
+  <target name="failureRecorder.internal">  
+    <property name="tmp.dir" value="out"/>
+    <!-- 
+    <delete>
+      <fileset dir="${tmp.dir}" includes="FailedTests*.class"/>
+    </delete>
+     -->
+    <!-- compile the FailedTests class if present --> 
+    <javac srcdir="${tmp.dir}" destdir="${tmp.dir}"/>
+    <available file="${tmp.dir}/FailedTests.class" property="hasFailingTests"/>
+    <junit haltonerror="false" haltonfailure="false">
+      <sysproperty key="ant.junit.failureCollector" 
value="${tmp.dir}/FailedTests"/>
+      <classpath>
+        <pathelement location="${tmp.dir}"/>
+      </classpath>
+      <batchtest todir="${tmp.dir}" unless="hasFailingTests">
+        <fileset dir="${tmp.dir}" includes="**/*.java" 
excludes="**/FailedTests.*"/>
+        <!-- for initial creation of the FailingTests.java -->
+        <formatter type="failure"/>
+        <!-- I want to see something ... -->
+        <formatter type="plain" usefile="false"/>
+      </batchtest>
+      <test name="FailedTests" if="hasFailingTests">
+       <!-- update the FailingTests.java -->
+        <formatter type="failure"/>
+        <!-- again, I want to see something -->
+        <formatter type="plain" usefile="false"/>
+      </test>
+    </junit>
+  </target>
+  
+  <target name="failureRecorder.runtest">
+       <ant target="failureRecorder.internal" antfile="junit.xml" 
inheritAll="false"/>
+  </target>
+  
+  <target name="failureRecorder.fixing">
+    <property name="tmp.dir" value="out"/>
+    <echo file="${tmp.dir}/A.java">
+        import junit.framework.*;
+        public class A extends TestCase {
+            public A(String s) { super(s); }
+            public void test01() { System.out.println("A.test01"); }
+            public void test02() { System.out.println("A.test02"); }
+            public void test03() { System.out.println("A.test03"); }
+      }
+    </echo>
+  </target>
+
 </project>

Added: 
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java?view=auto&rev=563053
==============================================================================
--- 
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java
 (added)
+++ 
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java
 Mon Aug  6 00:55:07 2007
@@ -0,0 +1,200 @@
+package org.apache.tools.ant.taskdefs.optional.junit;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.OutputStream;
+import java.io.PrintWriter;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.HashSet;
+import java.util.Iterator;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * <p>Collects all failing test <i>cases</i> and creates a new JUnit test 
class containing 
+ * a suite() method which calls these failed tests.</p>
+ * <p>Having classes <i>A</i> ... <i>D</i> with each several testcases you 
could earn a new
+ * test class like
+ * <pre>
+ * // generated on: 2007.08.06 09:42:34,555
+ * import junit.framework.*;
+ * public class FailedTests extends TestCase {
+ *     public FailedTests(String s) {
+ *         super(s);
+ *     }
+ *     public static Test suite() {
+ *         TestSuite suite = new TestSuite();
+ *         suite.addTest( new B("test04") );
+ *         suite.addTest( new org.D("test10") );
+ *         return suite;
+ *     }
+ * }
+ * </pre> 
+ * 
+ * @since Ant 1.7.1
+ */
+/*
+ * Because each running test case gets its own formatter, we collect
+ * the failing test cases in a static list. Because we dont have a finalizer
+ * method in the formatters "lifecycle", we regenerate the new java source
+ * at each end of a test suite. The last run will contain all failed tests.
+ */
+public class FailureRecorder implements JUnitResultFormatter {
+    
+    /** 
+     * This is the name of a magic System property ([EMAIL PROTECTED]). The 
value of this 
+     * <b>System</b> property should point to the location where to store the 
+     * generated class (without suffix).
+     * Default location and name is defined in DEFAULT_CLASS_LOCATION.
+     * @see #DEFAULT_CLASS_LOCATION
+     */
+    public static final String MAGIC_PROPERTY_CLASS_LOCATION = 
"ant.junit.failureCollector";
+
+    /** Default location and name for the generated JUnit class file. [EMAIL 
PROTECTED] */
+    public static final String DEFAULT_CLASS_LOCATION = 
System.getProperty("java.io.tmpdir") + "FailedTests";
+    
+    /** Class names of failed tests without duplicates. */
+    private static HashSet/*<Test>*/ failedTests = new HashSet();
+    
+    /** A writer for writing the generated source to. */
+    private PrintWriter writer;
+    
+    /**
+     * Location and name of the generated JUnit class. 
+     * Lazy instantiated via getLocationName().
+     */
+    private static String locationName;
+    
+    //TODO: Dont set the locationName via System.getProperty - better
+    //      via Ant properties. But how to access these?
+    private String getLocationName() {
+        if (locationName == null) {
+            String propValue = 
System.getProperty(MAGIC_PROPERTY_CLASS_LOCATION);
+            locationName = (propValue != null) ? propValue : 
DEFAULT_CLASS_LOCATION;
+        }
+        return locationName;
+    }
+
+    /**
+     * After each test suite, the whole new JUnit class will be regenerated. 
+     * @see 
org.apache.tools.ant.taskdefs.optional.junit.JUnitResultFormatter#endTestSuite(org.apache.tools.ant.taskdefs.optional.junit.JUnitTest)
+     */
+    public void endTestSuite(JUnitTest suite) throws BuildException {
+        if (failedTests.isEmpty()) return;
+        try {
+            File sourceFile = new File(getLocationName() + ".java");
+            sourceFile.delete();
+            writer = new PrintWriter(new FileOutputStream(sourceFile));
+
+            createClassHeader();
+            createTestSuiteHeader();
+            for (Iterator iter = failedTests.iterator(); iter.hasNext();) {
+                Test test = (Test) iter.next();
+                if (test!=null) {
+                    createAddTestToSuite(test);
+                }
+            }
+            createTestSuiteFooter();
+            createClassFooter();
+            
+            FileUtils.close(writer);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+    }
+    
+    public void addError(Test test, Throwable throwable) {
+        failedTests.add(test);
+    }
+
+    public void addFailure(Test test, AssertionFailedError error) {
+        failedTests.add(test);
+    }
+
+    public void setOutput(OutputStream out) {
+        // not in use
+    }
+
+    public void setSystemError(String err) {
+        // not in use
+    }
+
+    public void setSystemOutput(String out) {
+        // not in use
+    }
+
+    public void startTestSuite(JUnitTest suite) throws BuildException {
+        // not in use
+    }
+
+    public void endTest(Test test) {
+        // not in use
+    }
+
+    public void startTest(Test test) {
+        // not in use
+    }
+    
+    // "Templates" for generating the JUnit class
+    
+    private void createClassHeader() {
+        String className = getLocationName().replace('\\', '/');
+        if (className.indexOf('/') > -1) {
+            className = className.substring(className.lastIndexOf('/')+1);
+        }
+        SimpleDateFormat sdf = new SimpleDateFormat("yyyy.MM.dd HH:mm:ss,SSS");
+        writer.print("// generated on: ");
+        writer.println(sdf.format(new Date()));
+        writer.println("import junit.framework.*;");
+        writer.print("public class ");
+        writer.print( className );
+        // If this class does not extend TC, Ant doesnt run these
+        writer.println(" extends TestCase {");
+        // no-arg constructor
+        writer.print("    public ");
+        writer.print(className);
+        writer.println("(String s) {");
+        writer.println("        super(s);");
+        writer.println("    }");
+    }
+    
+    private void createTestSuiteHeader() {
+        writer.println("    public static Test suite() {");
+        writer.println("        TestSuite suite = new TestSuite();");
+    }
+    
+    private void createAddTestToSuite(Test test) {
+        writer.print("        suite.addTest( new ");
+        writer.print( getClassName(test) );
+        writer.print("(\"");
+        writer.print( getMethodName(test) );
+        writer.println("\") );");
+    }
+
+    private void createTestSuiteFooter() {
+        writer.println("        return suite;");
+        writer.println("    }");
+    }
+    
+    private void createClassFooter() {
+        writer.println("}");
+    }
+    
+    // Helper methods
+    
+    private String getMethodName(Test test) {
+        String methodName = test.toString();
+        return methodName.substring(0, methodName.indexOf('('));
+    }
+
+    private String getClassName(Test test) {
+        return test.getClass().getName();
+    }
+    
+}

Modified: 
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java?view=diff&rev=563053&r1=563052&r2=563053
==============================================================================
--- 
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java
 (original)
+++ 
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/FormatterElement.java
 Mon Aug  6 00:55:07 2007
@@ -47,6 +47,7 @@
  * @see XMLJUnitResultFormatter
  * @see BriefJUnitResultFormatter
  * @see PlainJUnitResultFormatter
+ * @see FailureRecorder
  * @see JUnitResultFormatter
  */
 public class FormatterElement {
@@ -68,6 +69,9 @@
     /** plain formatter class */
     public static final String PLAIN_FORMATTER_CLASS_NAME =
         
"org.apache.tools.ant.taskdefs.optional.junit.PlainJUnitResultFormatter";
+    /** failure recorder class */
+    public static final String FAILURE_RECORDER_CLASS_NAME =
+        "org.apache.tools.ant.taskdefs.optional.junit.FailureRecorder";
 
     /**
      * <p> Quick way to use a standard formatter.
@@ -77,6 +81,7 @@
      * <li> The <code>xml</code> type uses a 
<code>XMLJUnitResultFormatter</code>.
      * <li> The <code>brief</code> type uses a 
<code>BriefJUnitResultFormatter</code>.
      * <li> The <code>plain</code> type (the default) uses a 
<code>PlainJUnitResultFormatter</code>.
+     * <li> The <code>failure</code> type uses a <code>FailureRecorder</code>.
      * </ul>
      *
      * <p> Sets <code>classname</code> attribute - so you can't use that
@@ -84,13 +89,18 @@
      * @param type the enumerated value to use.
      */
     public void setType(TypeAttribute type) {
+        //TODO: Besseren Zugriffsalgorithums: TypeAttribut.getClassname()
         if ("xml".equals(type.getValue())) {
             setClassname(XML_FORMATTER_CLASS_NAME);
         } else {
             if ("brief".equals(type.getValue())) {
                 setClassname(BRIEF_FORMATTER_CLASS_NAME);
-            } else { // must be plain, ensured by TypeAttribute
-                setClassname(PLAIN_FORMATTER_CLASS_NAME);
+            } else {
+                if ("failure".equals(type.getValue())) {
+                    setClassname(FAILURE_RECORDER_CLASS_NAME);
+                } else { // must be plain, ensured by TypeAttribute
+                    setClassname(PLAIN_FORMATTER_CLASS_NAME);
+                }
             }
         }
     }
@@ -268,14 +278,14 @@
     }
 
     /**
-     * <p> Enumerated attribute with the values "plain", "xml" and "brief".
+     * <p> Enumerated attribute with the values "plain", "xml", "brief" and 
"failure".
      *
      * <p> Use to enumerate options for <code>type</code> attribute.
      */
     public static class TypeAttribute extends EnumeratedAttribute {
         /** [EMAIL PROTECTED] */
         public String[] getValues() {
-            return new String[] {"plain", "xml", "brief"};
+            return new String[] {"plain", "xml", "brief", "failure"};
         }
     }
 }

Modified: 
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java?view=diff&rev=563053&r1=563052&r2=563053
==============================================================================
--- 
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
 (original)
+++ 
ant/core/trunk/src/main/org/apache/tools/ant/taskdefs/optional/junit/JUnitTask.java
 Mon Aug  6 00:55:07 2007
@@ -163,7 +163,7 @@
     private JUnitTaskMirror delegate;
 
     /** A boolean on whether to get the forked path for ant classes */
-    private boolean   forkedPathChecked = false;
+    private boolean forkedPathChecked = false;
 
     //   Attributes for basetest
     private boolean haltOnError = false;

Modified: ant/core/trunk/src/tests/junit/org/apache/tools/ant/BuildFileTest.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/tests/junit/org/apache/tools/ant/BuildFileTest.java?view=diff&rev=563053&r1=563052&r2=563053
==============================================================================
--- ant/core/trunk/src/tests/junit/org/apache/tools/ant/BuildFileTest.java 
(original)
+++ ant/core/trunk/src/tests/junit/org/apache/tools/ant/BuildFileTest.java Mon 
Aug  6 00:55:07 2007
@@ -18,11 +18,11 @@
 
 package org.apache.tools.ant;
 
-import junit.framework.TestCase;
 import java.io.File;
 import java.io.PrintStream;
 import java.net.URL;
-import java.util.Hashtable;
+
+import junit.framework.TestCase;
 
 /**
  * A BuildFileTest is a TestCase which executes targets from an Ant buildfile
@@ -117,18 +117,35 @@
 
     /**
      * Assert that the given substring is in the output messages.
+     * @param message Print this message if the test fails. Defaults to 
+     *                a meaningful text if <tt>null</tt> is passed.  
+     * @since Ant1.7
+     */
+    public void assertOutputContaining(String message, String substring) {
+        String realOutput = getOutput();
+        String realMessage = (message != null) 
+            ? message 
+            : "expecting output to contain \"" + substring + "\" output was 
\"" + realOutput + "\"";
+        assertTrue(realMessage, realOutput.indexOf(substring) >= 0);
+    }
+
+    /**
+     * Assert that the given substring is not in the output messages.
+     * @param message Print this message if the test fails. Defaults to 
+     *                a meaningful text if <tt>null</tt> is passed.  
      * @since Ant1.7
      */
-    public void assertOutputContaining(String substring) {
+    public void assertOutputNotContaining(String message, String substring) {
         String realOutput = getOutput();
-        assertTrue("expecting output to contain \"" + substring
-                   + "\" output was \"" + realOutput + "\"",
-                   realOutput.indexOf(substring) >= 0);
+        String realMessage = (message != null) 
+            ? message 
+            : "expecting output to contain \"" + substring + "\" output was 
\"" + realOutput + "\"";
+        assertFalse(realMessage, realOutput.indexOf(substring) >= 0);
     }
 
     /**
-     * Assert that the given message has been logged with a priority
-     * &lt;= INFO when running the given target.
+     * Assert that the given message has been logged with a priority &lt;= 
INFO when running the
+     * given target.
      */
     public void expectLogContaining(String target, String log) {
         executeTarget(target);

Modified: 
ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java
URL: 
http://svn.apache.org/viewvc/ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java?view=diff&rev=563053&r1=563052&r2=563053
==============================================================================
--- 
ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java
 (original)
+++ 
ant/core/trunk/src/tests/junit/org/apache/tools/ant/taskdefs/optional/junit/JUnitTaskTest.java
 Mon Aug  6 00:55:07 2007
@@ -17,31 +17,31 @@
  */
 package org.apache.tools.ant.taskdefs.optional.junit;
 
-import org.apache.tools.ant.BuildFileTest;
 import java.io.BufferedReader;
+import java.io.File;
 import java.io.FileReader;
 import java.io.IOException;
 
+import org.apache.tools.ant.BuildFileTest;
+
 public class JUnitTaskTest extends BuildFileTest {
 
     /**
-     * Constructor for the JUnitTaskTest object
+     * Constructor for the JUnitTaskTest object.
      */
     public JUnitTaskTest(String name) {
         super(name);
     }
 
-
     /**
-     * The JUnit setup method
+     * The JUnit setup method.
      */
     public void setUp() {
         configureProject("src/etc/testcases/taskdefs/optional/junit.xml");
     }
 
-
     /**
-     * The teardown method for JUnit
+     * The teardown method for JUnit.
      */
     public void tearDown() {
         executeTarget("cleanup");
@@ -86,7 +86,83 @@
     public void testBatchTestForkOnceExtension() {
         assertResultFilesExist("testBatchTestForkOnceExtension", ".foo");
     }
-
+    
+    /* Bugzilla Report 42984 */
+    //TODO This scenario works from command line, but not from JUnit ...
+    //     See the _run.bat attachement of the bug.
+    public void _testFailureRecorder() {
+        File testDir = new File(getProjectDir(), "out");
+        File collectorFile = new File(getProjectDir(), "out/FailedTests.java");
+
+        // ensure that there is a clean test environment
+        assertFalse("Test directory must not exist before the test 
preparation.", 
+                testDir.exists());
+        assertFalse("The collector file must not exist before the test 
preparation.", 
+                collectorFile.exists());
+
+        // prepare the test environment
+        executeTarget("failureRecorder.prepare");
+        assertTrue("Test directory was not created.", testDir.exists());
+        assertTrue("There should be one class.", (new File(testDir, 
"A.class")).exists());
+        assertFalse("The collector file " + collectorFile.getAbsolutePath() 
+                + " should not exist before the 1st run.", 
collectorFile.exists());
+
+        // 1st junit run: should do all tests - failing and not failing tests
+        executeTarget("failureRecorder.runtest");
+        assertTrue("The collector file " + collectorFile.getAbsolutePath() 
+                + " should exist after the 1st run.", collectorFile.exists());
+        // the passing test cases
+        assertOutputContaining("1st run: should run A.test01", "A.test01");
+        assertOutputContaining("1st run: should run B.test05", "B.test05");
+        assertOutputContaining("1st run: should run B.test06", "B.test06");
+        assertOutputContaining("1st run: should run C.test07", "C.test07");
+        assertOutputContaining("1st run: should run C.test08", "C.test08");
+        assertOutputContaining("1st run: should run C.test09", "C.test09");
+        // the failing test cases
+        assertOutputContaining("1st run: should run A.test02", "A.test02");
+        assertOutputContaining("1st run: should run A.test03", "A.test03");
+        assertOutputContaining("1st run: should run B.test04", "B.test04");
+        assertOutputContaining("1st run: should run D.test10", "D.test10");
+
+        // 2nd junit run: should do only failing tests
+        executeTarget("failureRecorder.runtest");
+        assertTrue("The collector file " + collectorFile.getAbsolutePath() 
+                + " should exist after the 2nd run.", collectorFile.exists());
+        // the passing test cases
+        assertOutputNotContaining("2nd run: should not run A.test01", 
"A.test01");
+        assertOutputNotContaining("2nd run: should not run A.test05", 
"B.test05");
+        assertOutputNotContaining("2nd run: should not run B.test06", 
"B.test06");
+        assertOutputNotContaining("2nd run: should not run C.test07", 
"C.test07");
+        assertOutputNotContaining("2nd run: should not run C.test08", 
"C.test08");
+        assertOutputNotContaining("2nd run: should not run C.test09", 
"C.test09");
+        // the failing test cases
+        assertOutputContaining("2nd run: should run A.test02", "A.test02");
+        assertOutputContaining("2nd run: should run A.test03", "A.test03");
+        assertOutputContaining("2nd run: should run B.test04", "B.test04");
+        assertOutputContaining("2nd run: should run D.test10", "D.test10");
+        
+        // "fix" errors in class A
+        executeTarget("failureRecorder.fixing");
+        
+        // 3rd run: four running tests with two errors
+        executeTarget("failureRecorder.runtest");
+        assertTrue("The collector file " + collectorFile.getAbsolutePath() 
+                + " should exist after the 3rd run.", collectorFile.exists());
+        assertOutputContaining("3rd run: should run A.test02", "A.test02");
+        assertOutputContaining("3rd run: should run A.test03", "A.test03");
+        assertOutputContaining("3rd run: should run B.test04", "B.test04");
+        assertOutputContaining("3rd run: should run D.test10", "D.test10");
+        
+        // 4rd run: two running tests with errors
+        executeTarget("failureRecorder.runtest");
+        assertTrue("The collector file " + collectorFile.getAbsolutePath() 
+                + " should exist after the 4th run.", collectorFile.exists());
+        assertOutputNotContaining("4th run: should not run A.test02", 
"A.test02");
+        assertOutputNotContaining("4th run: should not run A.test03", 
"A.test03");
+        assertOutputContaining("4th run: should run B.test04", "B.test04");
+        assertOutputContaining("4th run: should run D.test10", "D.test10");
+    }
+    
     public void testBatchTestForkOnceCustomFormatter() {
         assertResultFilesExist("testBatchTestForkOnceCustomFormatter", "foo");
     }
@@ -155,5 +231,4 @@
         assertEquals(search, line);
     }
 
-}
-
+}
\ No newline at end of file



---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to