Submitted by: Stephane Bailliez <sbailliez@imediation.com> git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@268557 13f79535-47bb-0310-9956-ffa450edef68master
@@ -69,75 +69,140 @@ import java.io.File; | |||||
* @author <a href="mailto:jeff.martin@synamic.co.uk">Jeff Martin</a> | * @author <a href="mailto:jeff.martin@synamic.co.uk">Jeff Martin</a> | ||||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | ||||
* @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a> | * @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a> | ||||
* | |||||
* @see JUnitTest | |||||
*/ | */ | ||||
public final class BatchTest extends BaseTest { | public final class BatchTest extends BaseTest { | ||||
/** the reference to the project */ | |||||
private Project project; | private Project project; | ||||
/** the list of filesets containing the testcase filename rules */ | |||||
private Vector filesets = new Vector(); | private Vector filesets = new Vector(); | ||||
/** | |||||
* create a new batchtest instance | |||||
* @param project the project it depends on. | |||||
*/ | |||||
public BatchTest(Project project){ | public BatchTest(Project project){ | ||||
this.project = project; | this.project = project; | ||||
} | } | ||||
/** | |||||
* Add a new fileset instance to this batchtest. Whatever the fileset is, | |||||
* only filename that are <tt>.java</tt> or <tt>.class</tt> will be | |||||
* considered as 'candidates'. | |||||
* @param fs the new fileset containing the rules to get the testcases. | |||||
*/ | |||||
public void addFileSet(FileSet fs) { | public void addFileSet(FileSet fs) { | ||||
filesets.addElement(fs); | filesets.addElement(fs); | ||||
} | } | ||||
/** | |||||
* return all <tt>JUnitTest</tt> instances obtain by applying the fileset rules. | |||||
* @return an enumeration of all elements of this batchtest that are | |||||
* a <tt>JUnitTest</tt> instance. | |||||
* @see addTestsTo(Vector) | |||||
*/ | |||||
public final Enumeration elements(){ | public final Enumeration elements(){ | ||||
return new FileList(); | |||||
JUnitTest[] tests = createAllJUnitTest(); | |||||
return Enumerations.fromArray(tests); | |||||
} | } | ||||
public class FileList implements Enumeration{ | |||||
private String files[]=null; | |||||
private int i=0; | |||||
private FileList(){ | |||||
Vector v = new Vector(); | |||||
for (int j=0; j<filesets.size(); j++) { | |||||
FileSet fs = (FileSet) filesets.elementAt(j); | |||||
DirectoryScanner ds = fs.getDirectoryScanner(project); | |||||
ds.scan(); | |||||
String[] f = ds.getIncludedFiles(); | |||||
for (int k=0; k<f.length; k++) { | |||||
if (f[k].endsWith(".java")) { | |||||
v.addElement(f[k].substring(0, f[k].length()-5)); | |||||
} else if (f[k].endsWith(".class")) { | |||||
v.addElement(f[k].substring(0, f[k].length()-6)); | |||||
} | |||||
} | |||||
} | |||||
files = new String[v.size()]; | |||||
v.copyInto(files); | |||||
/** | |||||
* Convenient method to merge the <tt>JUnitTest</tt>s of this batchtest | |||||
* to a <tt>Vector</tt>. | |||||
* @param v the vector to which should be added all individual tests of this | |||||
* batch test. | |||||
*/ | |||||
final void addTestsTo(Vector v){ | |||||
JUnitTest[] tests = createAllJUnitTest(); | |||||
v.ensureCapacity( v.size() + tests.length); | |||||
for (int i = 0; i < tests.length; i++) { | |||||
v.addElement(tests[i]); | |||||
} | } | ||||
} | |||||
public final boolean hasMoreElements(){ | |||||
if(i<files.length)return true; | |||||
return false; | |||||
/** | |||||
* Create all <tt>JUnitTest</tt>s based on the filesets. Each instance | |||||
* is configured to match this instance properties. | |||||
* @return the array of all <tt>JUnitTest</tt>s that belongs to this batch. | |||||
*/ | |||||
private JUnitTest[] createAllJUnitTest(){ | |||||
String[] filenames = getFilenames(); | |||||
JUnitTest[] tests = new JUnitTest[filenames.length]; | |||||
for (int i = 0; i < tests.length; i++) { | |||||
String classname = javaToClass(filenames[i]); | |||||
tests[i] = createJUnitTest(classname); | |||||
} | } | ||||
return tests; | |||||
} | |||||
public final Object nextElement() throws NoSuchElementException{ | |||||
if(hasMoreElements()){ | |||||
JUnitTest test = new JUnitTest(javaToClass(files[i])); | |||||
test.setHaltonerror(haltOnError); | |||||
test.setHaltonfailure(haltOnFail); | |||||
test.setFork(fork); | |||||
test.setIf(ifProperty); | |||||
test.setUnless(unlessProperty); | |||||
test.setTodir(destDir); | |||||
Enumeration list = formatters.elements(); | |||||
while (list.hasMoreElements()) { | |||||
test.addFormatter((FormatterElement)list.nextElement()); | |||||
/** | |||||
* Iterate over all filesets and return the filename of all files | |||||
* that end with <tt>.java</tt> or <tt>.class</tt>. This is to avoid | |||||
* wrapping a <tt>JUnitTest</tt> over an xml file for example. A Testcase | |||||
* is obviouslly a java file (compiled or not). | |||||
* @return an array of filenames without their extension. As they should | |||||
* normally be taken from their root, filenames should match their fully | |||||
* qualified class name (If it is not the case it will fail when running the test). | |||||
* For the class <tt>org/apache/Whatever.class</tt> it will return <tt>org/apache/Whatever</tt>. | |||||
*/ | |||||
private String[] getFilenames(){ | |||||
Vector v = new Vector(); | |||||
final int size = this.filesets.size(); | |||||
for (int j=0; j<size; j++) { | |||||
FileSet fs = (FileSet) filesets.elementAt(j); | |||||
DirectoryScanner ds = fs.getDirectoryScanner(project); | |||||
ds.scan(); | |||||
String[] f = ds.getIncludedFiles(); | |||||
for (int k = 0; k < f.length; k++) { | |||||
String pathname = f[k]; | |||||
if (pathname.endsWith(".java")) { | |||||
v.addElement(pathname.substring(0, pathname.length()-".java".length())); | |||||
} else if (pathname.endsWith(".class")) { | |||||
v.addElement(pathname.substring(0, pathname.length()-".class".length())); | |||||
} | } | ||||
i++; | |||||
return test; | |||||
} | } | ||||
throw new NoSuchElementException(); | |||||
} | } | ||||
public final String javaToClass(String fileName){ | |||||
return fileName.replace(java.io.File.separatorChar, '.'); | |||||
String[] files = new String[v.size()]; | |||||
v.copyInto(files); | |||||
return files; | |||||
} | |||||
/** | |||||
* convenient method to convert a pathname without extension to a | |||||
* fully qualified classname. For example <tt>org/apache/Whatever</tt> will | |||||
* be converted to <tt>org.apache.Whatever</tt> | |||||
* @param filename the filename to "convert" to a classname. | |||||
* @return the classname matching the filename. | |||||
*/ | |||||
public final static String javaToClass(String filename){ | |||||
return filename.replace(File.separatorChar, '.'); | |||||
} | |||||
/** | |||||
* Create a <tt>JUnitTest</tt> that has the same property as this | |||||
* <tt>BatchTest</tt> instance. | |||||
* @param classname the name of the class that should be run as a | |||||
* <tt>JUnitTest</tt>. It must be a fully qualified name. | |||||
* @return the <tt>JUnitTest</tt> over the given classname. | |||||
*/ | |||||
private JUnitTest createJUnitTest(String classname){ | |||||
JUnitTest test = new JUnitTest(); | |||||
test.setName(classname); | |||||
test.setHaltonerror(this.haltOnError); | |||||
test.setHaltonfailure(this.haltOnFail); | |||||
test.setFork(this.fork); | |||||
test.setIf(this.ifProperty); | |||||
test.setUnless(this.unlessProperty); | |||||
test.setTodir(this.destDir); | |||||
Enumeration list = this.formatters.elements(); | |||||
while (list.hasMoreElements()) { | |||||
test.addFormatter((FormatterElement)list.nextElement()); | |||||
} | } | ||||
return test; | |||||
} | } | ||||
} | } |
@@ -64,29 +64,29 @@ import java.util.NoSuchElementException; | |||||
* @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a> | * @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a> | ||||
*/ | */ | ||||
public final class Enumerations { | public final class Enumerations { | ||||
private Enumerations(){ | |||||
} | |||||
private Enumerations(){ | |||||
} | |||||
/** | |||||
* creates an enumeration from an array of objects. | |||||
* @param array the array of object to enumerate. | |||||
* @return the enumeration over the array of objects. | |||||
*/ | |||||
public static Enumeration fromArray(Object[] array){ | |||||
return new ArrayEnumeration(array); | |||||
} | |||||
/** | |||||
* creates an enumeration from an array of objects. | |||||
* @param array the array of object to enumerate. | |||||
* @return the enumeration over the array of objects. | |||||
*/ | |||||
public static Enumeration fromArray(Object[] array){ | |||||
return new ArrayEnumeration(array); | |||||
} | |||||
/** | |||||
* creates an enumeration from an array of enumeration. The created enumeration | |||||
* will sequentially enumerate over all elements of each enumeration and skip | |||||
* <tt>null</tt> enumeration elements in the array. | |||||
* @param enums the array of enumerations. | |||||
* @return the enumeration over the array of enumerations. | |||||
*/ | |||||
public static Enumeration fromCompound(Enumeration[] enums){ | |||||
return new CompoundEnumeration(enums); | |||||
} | |||||
/** | |||||
* creates an enumeration from an array of enumeration. The created enumeration | |||||
* will sequentially enumerate over all elements of each enumeration and skip | |||||
* <tt>null</tt> enumeration elements in the array. | |||||
* @param enums the array of enumerations. | |||||
* @return the enumeration over the array of enumerations. | |||||
*/ | |||||
public static Enumeration fromCompound(Enumeration[] enums){ | |||||
return new CompoundEnumeration(enums); | |||||
} | |||||
} | } | ||||
@@ -96,47 +96,47 @@ public final class Enumerations { | |||||
* @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a> | * @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a> | ||||
*/ | */ | ||||
class ArrayEnumeration implements Enumeration { | class ArrayEnumeration implements Enumeration { | ||||
/** object array */ | |||||
private Object[] array; | |||||
/** current index */ | |||||
private int pos; | |||||
/** | |||||
* Initialize a new enumeration that wraps an array. | |||||
* @param array the array of object to enumerate. | |||||
*/ | |||||
public ArrayEnumeration(Object[] array){ | |||||
this.array = array; | |||||
this.pos = 0; | |||||
} | |||||
/** | |||||
* Tests if this enumeration contains more elements. | |||||
* | |||||
* @return <code>true</code> if and only if this enumeration object | |||||
* contains at least one more element to provide; | |||||
* <code>false</code> otherwise. | |||||
*/ | |||||
public boolean hasMoreElements() { | |||||
return (pos < array.length); | |||||
} | |||||
/** object array */ | |||||
private Object[] array; | |||||
/** current index */ | |||||
private int pos; | |||||
/** | |||||
* Initialize a new enumeration that wraps an array. | |||||
* @param array the array of object to enumerate. | |||||
*/ | |||||
public ArrayEnumeration(Object[] array){ | |||||
this.array = array; | |||||
this.pos = 0; | |||||
} | |||||
/** | |||||
* Tests if this enumeration contains more elements. | |||||
* | |||||
* @return <code>true</code> if and only if this enumeration object | |||||
* contains at least one more element to provide; | |||||
* <code>false</code> otherwise. | |||||
*/ | |||||
public boolean hasMoreElements() { | |||||
return (pos < array.length); | |||||
} | |||||
/** | |||||
* Returns the next element of this enumeration if this enumeration | |||||
* object has at least one more element to provide. | |||||
* | |||||
* @return the next element of this enumeration. | |||||
* @throws NoSuchElementException if no more elements exist. | |||||
*/ | |||||
public Object nextElement() throws NoSuchElementException { | |||||
if (hasMoreElements()) { | |||||
Object o = array[pos]; | |||||
pos++; | |||||
return o; | |||||
} | |||||
throw new NoSuchElementException(); | |||||
} | |||||
/** | |||||
* Returns the next element of this enumeration if this enumeration | |||||
* object has at least one more element to provide. | |||||
* | |||||
* @return the next element of this enumeration. | |||||
* @throws NoSuchElementException if no more elements exist. | |||||
*/ | |||||
public Object nextElement() throws NoSuchElementException { | |||||
if (hasMoreElements()) { | |||||
Object o = array[pos]; | |||||
pos++; | |||||
return o; | |||||
} | |||||
throw new NoSuchElementException(); | |||||
} | |||||
} | } | ||||
/** | /** | ||||
* Convenient enumeration over an array of enumeration. For example: | * Convenient enumeration over an array of enumeration. For example: | ||||
@@ -170,46 +170,46 @@ class ArrayEnumeration implements Enumeration { | |||||
* @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a> | * @author <a href="mailto:sbailliez@imediation.com">Stephane Bailliez</a> | ||||
*/ | */ | ||||
class CompoundEnumeration implements Enumeration { | class CompoundEnumeration implements Enumeration { | ||||
/** enumeration array */ | |||||
private Enumeration[] enumArray; | |||||
/** index in the enums array */ | |||||
private int index = 0; | |||||
/** enumeration array */ | |||||
private Enumeration[] enumArray; | |||||
/** index in the enums array */ | |||||
private int index = 0; | |||||
public CompoundEnumeration(Enumeration[] enumarray) { | public CompoundEnumeration(Enumeration[] enumarray) { | ||||
this.enumArray = enumarray; | |||||
this.enumArray = enumarray; | |||||
} | } | ||||
/** | |||||
* Tests if this enumeration contains more elements. | |||||
* | |||||
* @return <code>true</code> if and only if this enumeration object | |||||
* contains at least one more element to provide; | |||||
* <code>false</code> otherwise. | |||||
*/ | |||||
/** | |||||
* Tests if this enumeration contains more elements. | |||||
* | |||||
* @return <code>true</code> if and only if this enumeration object | |||||
* contains at least one more element to provide; | |||||
* <code>false</code> otherwise. | |||||
*/ | |||||
public boolean hasMoreElements() { | public boolean hasMoreElements() { | ||||
while (index < enumArray.length) { | |||||
if (enumArray[index] != null && enumArray[index].hasMoreElements()) { | |||||
return true; | |||||
} | |||||
index++; | |||||
} | |||||
return false; | |||||
while (index < enumArray.length) { | |||||
if (enumArray[index] != null && enumArray[index].hasMoreElements()) { | |||||
return true; | |||||
} | |||||
index++; | |||||
} | |||||
return false; | |||||
} | } | ||||
/** | |||||
* Returns the next element of this enumeration if this enumeration | |||||
* object has at least one more element to provide. | |||||
* | |||||
* @return the next element of this enumeration. | |||||
* @throws NoSuchElementException if no more elements exist. | |||||
*/ | |||||
/** | |||||
* Returns the next element of this enumeration if this enumeration | |||||
* object has at least one more element to provide. | |||||
* | |||||
* @return the next element of this enumeration. | |||||
* @throws NoSuchElementException if no more elements exist. | |||||
*/ | |||||
public Object nextElement() throws NoSuchElementException { | public Object nextElement() throws NoSuchElementException { | ||||
if ( hasMoreElements() ) { | |||||
return enumArray[index].nextElement(); | |||||
} | |||||
throw new NoSuchElementException(); | |||||
if ( hasMoreElements() ) { | |||||
return enumArray[index].nextElement(); | |||||
} | |||||
throw new NoSuchElementException(); | |||||
} | } | ||||
} | } | ||||
@@ -213,10 +213,7 @@ public class JUnitTask extends Task { | |||||
public void addSysproperty(Environment.Variable sysp) { | public void addSysproperty(Environment.Variable sysp) { | ||||
commandline.addSysproperty(sysp); | commandline.addSysproperty(sysp); | ||||
} | } | ||||
/** | |||||
* create a classpath to use for forked jvm | |||||
*/ | |||||
public Path createClasspath() { | public Path createClasspath() { | ||||
return commandline.createClasspath(project).createPath(); | return commandline.createClasspath(project).createPath(); | ||||
} | } | ||||
@@ -260,21 +257,17 @@ public class JUnitTask extends Task { | |||||
*/ | */ | ||||
public void execute() throws BuildException { | public void execute() throws BuildException { | ||||
Enumeration list = getIndividualTests(); | Enumeration list = getIndividualTests(); | ||||
try { | |||||
while (list.hasMoreElements()) { | |||||
JUnitTest test = (JUnitTest)list.nextElement(); | |||||
if ( test.shouldRun(project)) { | |||||
execute(test); | |||||
} | |||||
while (list.hasMoreElements()) { | |||||
JUnitTest test = (JUnitTest)list.nextElement(); | |||||
if ( test.shouldRun(project)) { | |||||
execute(test); | |||||
} | } | ||||
} finally { | |||||
//@todo here we should run test aggregation (SBa) | |||||
} | } | ||||
} | } | ||||
protected void execute(JUnitTest test) throws BuildException { | protected void execute(JUnitTest test) throws BuildException { | ||||
// set the default values if not specified | // set the default values if not specified | ||||
//@todo should be moved to the test class (?) (SBa) | |||||
//@todo should be moved to the test class instead. | |||||
if (test.getTodir() == null) { | if (test.getTodir() == null) { | ||||
test.setTodir(project.resolveFile(".")); | test.setTodir(project.resolveFile(".")); | ||||
} | } | ||||
@@ -288,7 +281,7 @@ public class JUnitTask extends Task { | |||||
boolean wasKilled = false; | boolean wasKilled = false; | ||||
if (!test.getFork()) { | if (!test.getFork()) { | ||||
exitValue = executeInVM(test); | exitValue = executeInVM(test); | ||||
} else { | |||||
} else { | |||||
ExecuteWatchdog watchdog = createWatchdog(); | ExecuteWatchdog watchdog = createWatchdog(); | ||||
exitValue = executeAsForked(test, watchdog); | exitValue = executeAsForked(test, watchdog); | ||||
// null watchdog means no timeout, you'd better not check with null | // null watchdog means no timeout, you'd better not check with null | ||||
@@ -459,10 +452,9 @@ public class JUnitTask extends Task { | |||||
private FormatterElement[] mergeFormatters(JUnitTest test){ | private FormatterElement[] mergeFormatters(JUnitTest test){ | ||||
Vector feVector = (Vector)formatters.clone(); | Vector feVector = (Vector)formatters.clone(); | ||||
FormatterElement[] fes = test.getFormatters(); | |||||
FormatterElement[] feArray = new FormatterElement[feVector.size() + fes.length]; | |||||
test.addFormattersTo(feVector); | |||||
FormatterElement[] feArray = new FormatterElement[feVector.size()]; | |||||
feVector.copyInto(feArray); | feVector.copyInto(feArray); | ||||
System.arraycopy(fes, 0, feArray, feVector.size(), fes.length); | |||||
return feArray; | return feArray; | ||||
} | } | ||||
@@ -73,7 +73,10 @@ public class JUnitTest extends BaseTest { | |||||
/** the name of the result file */ | /** the name of the result file */ | ||||
private String outfile = null; | private String outfile = null; | ||||
// @todo this is duplicating TestResult information. Only the time is not | |||||
// part of the result. So we'd better derive a new class from TestResult | |||||
// and deal with it. (SB) | |||||
private long runs, failures, errors; | private long runs, failures, errors; | ||||
private long runTime; | private long runTime; | ||||
@@ -139,4 +142,14 @@ public class JUnitTest extends BaseTest { | |||||
formatters.copyInto(fes); | formatters.copyInto(fes); | ||||
return fes; | return fes; | ||||
} | } | ||||
/** | |||||
* Convenient method to add formatters to a vector | |||||
*/ | |||||
void addFormattersTo(Vector v){ | |||||
final int count = formatters.size(); | |||||
for (int i = 0; i < count; i++){ | |||||
v.addElement( formatters.elementAt(i) ); | |||||
} | |||||
} | |||||
} | } |
@@ -74,7 +74,7 @@ import junit.framework.TestCase; | |||||
* @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | * @author <a href="mailto:stefan.bodewig@epost.de">Stefan Bodewig</a> | ||||
*/ | */ | ||||
public class XMLJUnitResultFormatter implements JUnitResultFormatter { | |||||
public class XMLJUnitResultFormatter implements JUnitResultFormatter, XMLConstants { | |||||
private static DocumentBuilder getDocumentBuilder() { | private static DocumentBuilder getDocumentBuilder() { | ||||
try { | try { | ||||
@@ -88,7 +88,8 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter { | |||||
/** | /** | ||||
* Formatter for timings. | * Formatter for timings. | ||||
*/ | */ | ||||
private NumberFormat nf = NumberFormat.getInstance(); | |||||
private NumberFormat nf = NumberFormat.getInstance(Locale.US); | |||||
/** | /** | ||||
* The XML document. | * The XML document. | ||||
*/ | */ | ||||
@@ -121,19 +122,19 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter { | |||||
*/ | */ | ||||
public void startTestSuite(JUnitTest suite) { | public void startTestSuite(JUnitTest suite) { | ||||
doc = getDocumentBuilder().newDocument(); | doc = getDocumentBuilder().newDocument(); | ||||
rootElement = doc.createElement("testsuite"); | |||||
rootElement.setAttribute("name", suite.getName()); | |||||
rootElement = doc.createElement(TESTSUITE); | |||||
rootElement.setAttribute(ATTR_NAME, suite.getName()); | |||||
} | } | ||||
/** | /** | ||||
* The whole testsuite ended. | * The whole testsuite ended. | ||||
*/ | */ | ||||
public void endTestSuite(JUnitTest suite) throws BuildException { | public void endTestSuite(JUnitTest suite) throws BuildException { | ||||
rootElement.setAttribute("tests", ""+suite.runCount()); | |||||
rootElement.setAttribute("failures", ""+suite.failureCount()); | |||||
rootElement.setAttribute("errors", ""+suite.errorCount()); | |||||
rootElement.setAttribute("time", | |||||
nf.format(suite.getRunTime()/1000.0)+" sec"); | |||||
rootElement.setAttribute(ATTR_TESTS, ""+suite.runCount()); | |||||
rootElement.setAttribute(ATTR_FAILURES, ""+suite.failureCount()); | |||||
rootElement.setAttribute(ATTR_ERRORS, ""+suite.errorCount()); | |||||
rootElement.setAttribute(ATTR_TIME, | |||||
nf.format(suite.getRunTime()/1000.0)); | |||||
if (out != null) { | if (out != null) { | ||||
Writer wri = null; | Writer wri = null; | ||||
try { | try { | ||||
@@ -162,8 +163,8 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter { | |||||
*/ | */ | ||||
public void startTest(Test t) { | public void startTest(Test t) { | ||||
lastTestStart = System.currentTimeMillis(); | lastTestStart = System.currentTimeMillis(); | ||||
currentTest = doc.createElement("testcase"); | |||||
currentTest.setAttribute("name", ((TestCase) t).name()); | |||||
currentTest = doc.createElement(TESTCASE); | |||||
currentTest.setAttribute(ATTR_NAME, ((TestCase) t).name()); | |||||
rootElement.appendChild(currentTest); | rootElement.appendChild(currentTest); | ||||
} | } | ||||
@@ -173,7 +174,7 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter { | |||||
* <p>A Test is finished. | * <p>A Test is finished. | ||||
*/ | */ | ||||
public void endTest(Test test) { | public void endTest(Test test) { | ||||
currentTest.setAttribute("time", | |||||
currentTest.setAttribute(ATTR_TIME, | |||||
nf.format((System.currentTimeMillis()-lastTestStart) | nf.format((System.currentTimeMillis()-lastTestStart) | ||||
/ 1000.0)); | / 1000.0)); | ||||
} | } | ||||
@@ -184,7 +185,7 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter { | |||||
* <p>A Test failed. | * <p>A Test failed. | ||||
*/ | */ | ||||
public void addFailure(Test test, Throwable t) { | public void addFailure(Test test, Throwable t) { | ||||
formatError("failure", test, t); | |||||
formatError(FAILURE, test, t); | |||||
} | } | ||||
/** | /** | ||||
@@ -202,7 +203,7 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter { | |||||
* <p>An error occured while running the test. | * <p>An error occured while running the test. | ||||
*/ | */ | ||||
public void addError(Test test, Throwable t) { | public void addError(Test test, Throwable t) { | ||||
formatError("error", test, t); | |||||
formatError(ERROR, test, t); | |||||
} | } | ||||
private void formatError(String type, Test test, Throwable t) { | private void formatError(String type, Test test, Throwable t) { | ||||
@@ -219,9 +220,9 @@ public class XMLJUnitResultFormatter implements JUnitResultFormatter { | |||||
String message = t.getMessage(); | String message = t.getMessage(); | ||||
if (message != null && message.length() > 0) { | if (message != null && message.length() > 0) { | ||||
nested.setAttribute("message", t.getMessage()); | |||||
nested.setAttribute(ATTR_MESSAGE, t.getMessage()); | |||||
} | } | ||||
nested.setAttribute("type", t.getClass().getName()); | |||||
nested.setAttribute(ATTR_TYPE, t.getClass().getName()); | |||||
StringWriter swr = new StringWriter(); | StringWriter swr = new StringWriter(); | ||||
t.printStackTrace(new PrintWriter(swr, true)); | t.printStackTrace(new PrintWriter(swr, true)); | ||||