You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@ant.apache.org by jh...@apache.org on 2007/09/12 10:49:58 UTC

svn commit: r574848 - in /ant/antlibs/antunit/trunk: docs/failurelistener.html src/main/org/apache/ant/antunit/antlib.xml src/main/org/apache/ant/antunit/listener/FailureAntUnitListener.java

Author: jhm
Date: Wed Sep 12 01:49:57 2007
New Revision: 574848

URL: http://svn.apache.org/viewvc?rev=574848&view=rev
Log:
New Failure Listener, like the new one for JUnit.

Added:
    ant/antlibs/antunit/trunk/docs/failurelistener.html
    ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/listener/FailureAntUnitListener.java
Modified:
    ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/antlib.xml

Added: ant/antlibs/antunit/trunk/docs/failurelistener.html
URL: http://svn.apache.org/viewvc/ant/antlibs/antunit/trunk/docs/failurelistener.html?rev=574848&view=auto
==============================================================================
--- ant/antlibs/antunit/trunk/docs/failurelistener.html (added)
+++ ant/antlibs/antunit/trunk/docs/failurelistener.html Wed Sep 12 01:49:57 2007
@@ -0,0 +1,61 @@
+<!--
+Licensed to the Apache Software Foundation (ASF) under one
+or more contributor license agreements.  See the NOTICE file
+distributed with this work for additional information
+regarding copyright ownership.  The ASF licenses this file
+to you 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.
+-->
+<html>
+  <head>
+    <meta http-equiv="Content-Language" content="en-us"></meta>
+    <link rel="stylesheet" type="text/css" href="style.css">
+    <title>XMLListener AntUnit Listener</title>
+  </head>
+
+  <body>
+    <h2><a name="xmllistener">Failure AntUnit Listener</a></h2>
+
+    <h3>Description</h3>
+
+    <p>Writes reports similar to the &quot;failure&quot; JUnit formatter.</p><p>This AntUnitListener creates a new buildfile with a target for each failed test target in the AntUnit run. The generated target calls the failed target (with setUp and tearDown if present in the called project). <br></p><p>This is intended for rerunning just failed tests.<br></p>
+
+    
+
+    <h3>Parameters</h3>
+    <table border="1" cellpadding="2" cellspacing="0">
+      <tr>
+        <td valign="top"><b>Attribute</b></td>
+        <td valign="top"><b>Description</b></td>
+        <td align="center" valign="top"><b>Required</b></td>
+      </tr>
+      <tr>
+        <td valign="top">file</td>
+        <td valign="top">Where to write the generated buildfile.<br></td>
+        <td align="center">Yes.</td>
+      </tr>
+    </table>
+
+    <h3>Examples</h3>
+
+<pre> <br>    &lt;au:antunit&gt; 
+      &lt;fileset dir=&quot;${tests}&quot; includes=&quot;*.xml&quot;/&gt; 
+      &lt;au:failurelistener file=&quot;${build.dir}/failed-tests/failed.xml&quot;/&gt; 
+    &lt;/au:antunit&gt; <br>
+</pre>
+
+    <p>Runs AntUnit on all XML files in the directory
+    <code>${tests}</code> and collecting all failed tests. If there was a failure the file <code>${build.dir}/failed-tests/failed.xml</code> is created and has a <em>textXXX </em>target for each failed test. Additionally it has a default target <em>antunit</em> which runs all these failed tests.<br> </p>
+
+  </body>
+</html>

Modified: ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/antlib.xml
URL: http://svn.apache.org/viewvc/ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/antlib.xml?rev=574848&r1=574847&r2=574848&view=diff
==============================================================================
--- ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/antlib.xml (original)
+++ ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/antlib.xml Wed Sep 12 01:49:57 2007
@@ -33,6 +33,9 @@
   <typedef name="xmllistener"
     classname="org.apache.ant.antunit.listener.XMLAntUnitListener"/>
 
+  <typedef name="failurelistener"
+    classname="org.apache.ant.antunit.listener.FailureAntUnitListener"/>
+
   <typedef name="logcapturer"
            classname="org.apache.ant.antunit.LogCapturer"/>
 

Added: ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/listener/FailureAntUnitListener.java
URL: http://svn.apache.org/viewvc/ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/listener/FailureAntUnitListener.java?rev=574848&view=auto
==============================================================================
--- ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/listener/FailureAntUnitListener.java (added)
+++ ant/antlibs/antunit/trunk/src/main/org/apache/ant/antunit/listener/FailureAntUnitListener.java Wed Sep 12 01:49:57 2007
@@ -0,0 +1,208 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you 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.ant.antunit.listener;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.NumberFormat;
+import java.util.Iterator;
+import java.util.SortedSet;
+import java.util.TreeSet;
+
+import org.apache.ant.antunit.AssertionFailedException;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.util.FileUtils;
+
+/**
+ * This AntUnitListener creates a new buildfile with a target for each
+ * failed test target in the AntUnit run. The generated target calls
+ * the failed target (with setUp and tearDown if present in the called
+ * project). 
+ * This is intended for rerunning just failed tests.
+ */
+public class FailureAntUnitListener extends BaseAntUnitListener {
+ 
+    /** LineSeparator just for beautifying the output. */
+    private static final String BR = System.getProperty("line.separator"); 
+
+    /** A sorted list (without duplicates) of failed tests. */
+    private static SortedSet failedTests = new TreeSet();
+    
+    /** Where to write the generated buildfile. */
+    private static File failureBuildfile;
+    
+    /** The current running test project. Needed for addError()/addFailure(). */
+    private Project currentTestProject;
+
+    /** The current running build file. Needed for addError()/addFailure(). */
+    private String currentBuildFile;
+    
+    
+    /** No-arg constructor. */
+    public FailureAntUnitListener() {
+        super(new BaseAntUnitListener.SendLogTo(SendLogTo.ANT_LOG), "txt");
+    }
+
+    public void startTestSuite(Project testProject, String buildFile) {
+        super.startTestSuite(testProject, buildFile);
+        currentTestProject = testProject;
+        currentBuildFile = buildFile;
+    }
+    
+    public void addError(String target, Throwable ae) {
+        super.addError(target, ae);
+        failedTests.add(new TestInfos(currentTestProject, currentBuildFile, target, ae.getMessage()));
+    }
+    
+    public void addFailure(String target, AssertionFailedException ae) {
+        super.addFailure(target, ae);
+        failedTests.add(new TestInfos(currentTestProject, currentBuildFile, target, ae.getMessage()));
+    } 
+    
+    /** not in use */
+    public void endTest(String target) { 
+    }
+
+    public void endTestSuite(Project testProject, String buildFile) {
+        StringBuffer sb = new StringBuffer();
+        // <project> and antunit-target for direct run
+        sb.append("<project default=\"antunit\" xmlns:au=\"antlib:org.apache.ant.antunit\">");
+        sb.append(BR);
+        sb.append(BR);
+        sb.append("  <target name=\"antunit\">").append(BR);
+        sb.append("    <au:antunit>").append(BR);
+        sb.append("      <au:plainlistener/>").append(BR);
+        sb.append("      <file file=\"${ant.file}\"/>").append(BR);
+        sb.append("    </au:antunit>").append(BR);
+        sb.append("  </target>").append(BR);
+        sb.append(BR);
+        sb.append(BR);
+        
+        // one target for each failed test
+        int testNumber = 0;
+        NumberFormat f = NumberFormat.getIntegerInstance();
+        for (Iterator it = failedTests.iterator(); it.hasNext();) {
+            sb.append("  <target name=\"test");
+            sb.append(f.format(testNumber++));
+            sb.append("\">").append(BR);
+            TestInfos testInfos = (TestInfos) it.next();
+            sb.append(testInfos);
+            sb.append("  </target>").append(BR);
+            sb.append(BR);
+        }
+        
+        // close the <project>
+        sb.append("</project>").append(BR);
+        
+        // write the whole file
+        try {
+            FileOutputStream fos = new FileOutputStream(failureBuildfile);
+            fos.write(sb.toString().getBytes());
+            FileUtils.close(fos);
+        } catch (FileNotFoundException e) {
+            throw new BuildException(e);
+        } catch (IOException e) {
+            throw new BuildException(e);
+        }
+    }
+    
+    
+    /**
+     * Class for collecting needed information about failed tests.
+     */
+    public class TestInfos implements Comparable {
+        /** Does the project has a setUp target? */
+        boolean projectHasSetup = false;
+        
+        /** Does the project has a tearDown target? */
+        boolean projectHasTearDown = false;
+        
+        /** The called target. */
+        String target;
+        
+        /** The buildfile of the project. */
+        String buildfile;
+        
+        /** The error message which was shown. */
+        String errorMessage;
+        
+        public TestInfos(Project project, String buildfile, String target, String errorMessage) {
+            projectHasSetup = project.getTargets().containsKey("setUp");
+            projectHasTearDown = project.getTargets().containsKey("tearDown");
+            this.buildfile = buildfile;
+            this.target = target; 
+            this.errorMessage = errorMessage;
+        }
+        
+        /** 
+         * Creates an <ant> call according to the stored information. 
+         * @see java.lang.Object#toString()
+         */
+        public String toString() {
+            StringBuffer sb = new StringBuffer();
+            // make the reader of the buildfile happy
+            sb.append("    <!-- ");
+            sb.append(errorMessage);
+            sb.append(" -->").append(BR);
+            // <ant antfile="" inheritAll="false">
+            sb.append("    <ant ");
+            sb.append("antfile=\"");
+            sb.append(buildfile.replace('\\', '/'));
+            sb.append("\" ");
+            sb.append("inheritAll=\"false\">");
+            sb.append(BR);
+            // <target name=""/>
+            if (projectHasSetup) {
+                sb.append("      <target name=\"setUp\"/>").append(BR);
+            }
+            sb.append("      <target name=\"");
+            sb.append(target);
+            sb.append("\"/>");
+            sb.append(BR);
+            if (projectHasTearDown) {
+                sb.append("      <target name=\"tearDown\"/>").append(BR);
+            }
+            // </ant>
+            sb.append("    </ant>").append(BR);
+            return sb.toString();
+        }
+        
+        // Needed, so that a SortedSet could sort this class into the list.
+        public int compareTo(Object other) {
+            if (!(other instanceof TestInfos)) {
+                return -1;
+            } else {
+                TestInfos that = (TestInfos)other;
+                return this.toString().compareTo(that.toString());   
+            }
+        }
+    }
+
+
+
+    public void setFile(File file) {
+        this.failureBuildfile = file;
+    }
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@ant.apache.org
For additional commands, e-mail: dev-help@ant.apache.org