From f02f90064bbd969d79995103290b722750fe67ba Mon Sep 17 00:00:00 2001
From: Jan Materne
Date: Tue, 11 Sep 2007 11:36:53 +0000
Subject: [PATCH] * Refactoring of FailureRecorder: use of a helper class
instead of helper methods * FailureRecorder creates better names in the
generated testcase * just put in into Ant 1.8.0 * sorting of the failed tests
* javadoc * update the manual
git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@574554 13f79535-47bb-0310-9956-ffa450edef68
---
docs/manual/OptionalTasks/junit.html | 7 +-
.../optional/junit/FailureRecorder.java | 118 +++++++++++-------
2 files changed, 77 insertions(+), 48 deletions(-)
diff --git a/docs/manual/OptionalTasks/junit.html b/docs/manual/OptionalTasks/junit.html
index 5f295ab5d..0afee1f72 100644
--- a/docs/manual/OptionalTasks/junit.html
+++ b/docs/manual/OptionalTasks/junit.html
@@ -342,7 +342,7 @@ The name of the file is determined by the
name of the test and can be set by the outfile
attribute
of <test>
.
-There are three predefined formatters - one prints the test results
+
There are four predefined formatters - one prints the test results
in XML format, the other emits plain text. The formatter named
brief
will only print detailed information for testcases
that failed, while plain
gives a little statistics line
@@ -354,7 +354,8 @@ can be specified.
that your tests have written as some characters are illegal in XML
documents and will be dropped.
-The formatter named failure
collects all failing testXXX()
+
The fourth formatter named failure
(since Ant 1.8.0)
+collects all failing testXXX()
methods and creates a new TestCase
which delegates only these
failing methods. The name and the location can be specified via Java System property
ant.junit.failureCollector
. The value has to point to the directory and
@@ -375,7 +376,7 @@ time.
type |
Use a predefined formatter (either
- xml , plain , or brief ). |
+ xml
, plain
, brief
or failure
).
Exactly one of these. |
diff --git a/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java b/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java
index fae4726eb..6de86ca07 100644
--- a/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java
+++ b/src/main/org/apache/tools/ant/taskdefs/optional/junit/FailureRecorder.java
@@ -24,8 +24,9 @@ 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 java.util.SortedSet;
+import java.util.TreeSet;
import junit.framework.AssertionFailedError;
import junit.framework.Test;
@@ -42,8 +43,8 @@ import org.apache.tools.ant.util.FileUtils;
* // generated on: 2007.08.06 09:42:34,555
* import junit.framework.*;
* public class FailedTests extends TestCase {
- * public FailedTests(String s) {
- * super(s);
+ * public FailedTests(String testname) {
+ * super(testname);
* }
* public static Test suite() {
* TestSuite suite = new TestSuite();
@@ -59,7 +60,7 @@ import org.apache.tools.ant.util.FileUtils;
* 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.
- * @since Ant 1.7.1
+ * @since Ant 1.8.0
*/
public class FailureRecorder implements JUnitResultFormatter {
@@ -78,7 +79,7 @@ public class FailureRecorder implements JUnitResultFormatter {
= System.getProperty("java.io.tmpdir") + "FailedTests";
/** Class names of failed tests without duplicates. */
- private static HashSet/**/ failedTests = new HashSet();
+ private static SortedSet/**/ failedTests = new TreeSet();
/** A writer for writing the generated source to. */
private PrintWriter writer;
@@ -99,7 +100,7 @@ public class FailureRecorder implements JUnitResultFormatter {
return locationName;
}
- // CheckStyle:LineLengthCheck OFF - see is long
+ // CheckStyle:LineLengthCheck OFF - @see is long
/**
* After each test suite, the whole new JUnit class will be regenerated.
* @param suite the test suite
@@ -117,14 +118,7 @@ public class FailureRecorder implements JUnitResultFormatter {
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();
+ createSuiteMethod();
createClassFooter();
FileUtils.close(writer);
@@ -134,19 +128,21 @@ public class FailureRecorder implements JUnitResultFormatter {
}
/**
- * Not used
- * {@inheritDoc}
+ * Add the failed test to the list.
+ * @see junit.framework.TestListener#addError(junit.framework.Test, java.lang.Throwable)
*/
public void addError(Test test, Throwable throwable) {
- failedTests.add(test);
+ failedTests.add(new TestInfos(test));
}
+ // CheckStyle:LineLengthCheck OFF - @see is long
/**
- * Not used
- * {@inheritDoc}
+ * Add the failed test to the list.
+ * @see junit.framework.TestListener#addFailure(junit.framework.Test, junit.framework.AssertionFailedError)
*/
+ // CheckStyle:LineLengthCheck ON
public void addFailure(Test test, AssertionFailedError error) {
- failedTests.add(test);
+ failedTests.add(new TestInfos(test));
}
/**
@@ -215,42 +211,74 @@ public class FailureRecorder implements JUnitResultFormatter {
// no-arg constructor
writer.print(" public ");
writer.print(className);
- writer.println("(String s) {");
- writer.println(" super(s);");
+ writer.println("(String testname) {");
+ writer.println(" super(testname);");
writer.println(" }");
}
-
- private void createTestSuiteHeader() {
+
+ private void createSuiteMethod() {
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() {
+ for (Iterator iter = failedTests.iterator(); iter.hasNext();) {
+ TestInfos testInfos = (TestInfos) iter.next();
+ writer.print(" suite.addTest(");
+ writer.print(testInfos);
+ writer.println(");");
+ }
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();
+ // Helper classes
+
+ /**
+ * TestInfos holds information about a given test for later use.
+ */
+ public class TestInfos implements Comparable {
+
+ /** The class name of the test. */
+ String className;
+
+ /** The method name of the testcase. */
+ String methodName;
+
+ /**
+ * This constructor extracts the needed information from the given test.
+ * @param test Test to analyze
+ */
+ public TestInfos(Test test) {
+ className = test.getClass().getName();
+ methodName = test.toString();
+ methodName = methodName.substring(0, methodName.indexOf('('));
+ }
+
+ /**
+ * This String-Representation can directly be used for instantiation of
+ * the JUnit testcase.
+ * @see java.lang.Object#toString()
+ * @see FailureRecorder#createSuiteMethod()
+ */
+ public String toString() {
+ return "new " + className + "(\"" + methodName + "\")";
+ }
+
+ /*
+ * The SortedMap needs comparable elements.
+ * @see java.lang.Comparable#compareTo(T)
+ * @see SortedSet#comparator()
+ */
+ public int compareTo(Object other) {
+ if (other instanceof TestInfos) {
+ TestInfos otherInfos = (TestInfos) other;
+ return toString().compareTo(otherInfos.toString());
+ } else {
+ return -1;
+ }
+ }
}
}