- Added TestSummary (TestResult was better but is conflicting with JUnit) which sole purpose is to provide a helpful summary of the sequence to listeners. git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@271124 13f79535-47bb-0310-9956-ffa450edef68master
| @@ -116,19 +116,24 @@ public class Server { | |||
| } | |||
| /** start a server to the specified port */ | |||
| public void start() { | |||
| try { | |||
| start(false); | |||
| } catch (InterruptedException e){ | |||
| } | |||
| } | |||
| /** start a server to the specified port and wait for end */ | |||
| public void start(boolean flag) throws InterruptedException { | |||
| Worker worker = new Worker(); | |||
| worker.start(); | |||
| if (flag){ | |||
| worker.join(); | |||
| public void start(boolean loop) throws IOException { | |||
| server = new ServerSocket(port); | |||
| while (server != null) { | |||
| client = server.accept(); | |||
| messenger = new Messenger(client.getInputStream(), client.getOutputStream()); | |||
| TestRunEvent evt = null; | |||
| try { | |||
| while ( (evt = messenger.read()) != null ) { | |||
| dispatcher.dispatchEvent(evt); | |||
| } | |||
| } catch (Exception e){ | |||
| e.printStackTrace(); | |||
| //@fixme this stacktrace might be normal when closing | |||
| // the socket. So decompose the above in distinct steps | |||
| } | |||
| if (!loop){ | |||
| break; | |||
| } | |||
| } | |||
| } | |||
| @@ -169,26 +174,4 @@ public class Server { | |||
| } catch (IOException e) { | |||
| } | |||
| } | |||
| //----- | |||
| private class Worker extends Thread { | |||
| public void run() { | |||
| try { | |||
| server = new ServerSocket(port); | |||
| client = server.accept(); | |||
| messenger = new Messenger(client.getInputStream(), client.getOutputStream()); | |||
| TestRunEvent evt = null; | |||
| while ( (evt = messenger.read()) != null ) { | |||
| dispatcher.dispatchEvent(evt); | |||
| } | |||
| } catch (Exception e) { | |||
| //@fixme this stacktrace might be normal when closing | |||
| // the socket. So decompose the above in distinct steps | |||
| } finally { | |||
| cancel(); | |||
| shutdown(); | |||
| } | |||
| } | |||
| } | |||
| } | |||
| @@ -1,95 +0,0 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 The Apache Software Foundation. All rights | |||
| * reserved. | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * 1. Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * 2. Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in | |||
| * the documentation and/or other materials provided with the | |||
| * distribution. | |||
| * | |||
| * 3. The end-user documentation included with the redistribution, if | |||
| * any, must include the following acknowlegement: | |||
| * "This product includes software developed by the | |||
| * Apache Software Foundation (http://www.apache.org/)." | |||
| * Alternately, this acknowlegement may appear in the software itself, | |||
| * if and wherever such third-party acknowlegements normally appear. | |||
| * | |||
| * 4. The names "The Jakarta Project", "Ant", and "Apache Software | |||
| * Foundation" must not be used to endorse or promote products derived | |||
| * from this software without prior written permission. For written | |||
| * permission, please contact apache@apache.org. | |||
| * | |||
| * 5. Products derived from this software may not be called "Apache" | |||
| * nor may "Apache" appear in their names without prior written | |||
| * permission of the Apache Group. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
| * SUCH DAMAGE. | |||
| * ==================================================================== | |||
| * | |||
| * This software consists of voluntary contributions made by many | |||
| * individuals on behalf of the Apache Software Foundation. For more | |||
| * information on the Apache Software Foundation, please see | |||
| * <http://www.apache.org/>. | |||
| */ | |||
| package org.apache.tools.ant.taskdefs.optional.rjunit.remote; | |||
| import java.io.ByteArrayInputStream; | |||
| import java.io.ByteArrayOutputStream; | |||
| import java.io.ObjectInputStream; | |||
| import java.io.ObjectOutputStream; | |||
| /** | |||
| * A set of helper methods related to sockets. | |||
| * | |||
| * @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a> | |||
| */ | |||
| public class SocketUtil { | |||
| /** | |||
| * Helper method to deserialize an object | |||
| * @param bytes the binary data representing the serialized object. | |||
| * @return the deserialized object. | |||
| * @throws Exception a generic exception if an error occurs when | |||
| * deserializing the object. | |||
| */ | |||
| public static Object deserialize(byte[] bytes) throws Exception { | |||
| ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bytes)); | |||
| return ois.readObject(); | |||
| } | |||
| /** | |||
| * Helper method to serialize an object | |||
| * @param o the object to serialize. | |||
| * @return the binary data representing the serialized object. | |||
| * @throws Exception a generic exception if an error occurs when | |||
| * serializing the object. | |||
| */ | |||
| public static byte[] serialize(Object o) throws Exception { | |||
| ByteArrayOutputStream out = new ByteArrayOutputStream(); | |||
| ObjectOutputStream oos = new ObjectOutputStream(out); | |||
| oos.writeObject(o); | |||
| oos.close(); | |||
| return out.toByteArray(); | |||
| } | |||
| } | |||
| @@ -59,6 +59,9 @@ import java.util.Properties; | |||
| import org.apache.tools.ant.util.StringUtils; | |||
| /** | |||
| * Provide the basic events to be used during the tests. | |||
| * This is not very extensible but since the events should be somewhat | |||
| * limited, for now this is better to do it like this. | |||
| * | |||
| * @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a> | |||
| */ | |||
| @@ -81,7 +84,7 @@ public class TestRunEvent extends EventObject { | |||
| /** the type of event */ | |||
| private int type = -1; | |||
| /** timestamp for all tests */ | |||
| /** timestamp for all events */ | |||
| private long timestamp = System.currentTimeMillis(); | |||
| /** name of testcase(method name) or testsuite (classname) */ | |||
| @@ -93,19 +96,28 @@ public class TestRunEvent extends EventObject { | |||
| /** properties for end of testrun */ | |||
| private Properties props; | |||
| /** handy result for each end of sequence */ | |||
| private TestSummary result; | |||
| public TestRunEvent(Integer id, int type){ | |||
| super(id); | |||
| this.type = type; | |||
| } | |||
| public TestRunEvent(Integer id, int type, String name, TestSummary result){ | |||
| this(id, type, name); | |||
| this.result = result; | |||
| } | |||
| public TestRunEvent(Integer id, int type, String name){ | |||
| this(id, type); | |||
| this.name = name; | |||
| } | |||
| public TestRunEvent(Integer id, int type, Properties props){ | |||
| public TestRunEvent(Integer id, int type, Properties props, TestSummary result){ | |||
| this(id, type); | |||
| this.props = props; | |||
| this.result = result; | |||
| } | |||
| public TestRunEvent(Integer id, int type, String name, Throwable t){ | |||
| @@ -145,6 +157,10 @@ public class TestRunEvent extends EventObject { | |||
| return name; | |||
| } | |||
| public TestSummary getSummary(){ | |||
| return result; | |||
| } | |||
| public String getStackTrace(){ | |||
| return stacktrace; | |||
| } | |||
| @@ -160,7 +176,8 @@ public class TestRunEvent extends EventObject { | |||
| (timestamp == other.timestamp) && | |||
| ( name == null ? other.name == null : name.equals(other.name) ) && | |||
| ( stacktrace == null ? other.stacktrace == null : stacktrace.equals(other.stacktrace) ) && | |||
| ( props == null ? other.props == null : props.equals(other.props) ) ) ; | |||
| ( props == null ? other.props == null : props.equals(other.props) ) && | |||
| ( result == null ? other.result == null : result.equals(other.result) ) ); | |||
| } | |||
| return false; | |||
| } | |||
| @@ -62,6 +62,11 @@ import java.util.Properties; | |||
| import java.util.StringTokenizer; | |||
| import java.util.Vector; | |||
| import java.util.Random; | |||
| import java.util.Map; | |||
| import java.util.HashMap; | |||
| import java.util.ArrayList; | |||
| import java.util.Collection; | |||
| import java.util.Iterator; | |||
| import junit.framework.AssertionFailedError; | |||
| import junit.framework.Test; | |||
| @@ -71,6 +76,8 @@ import junit.framework.TestResult; | |||
| import junit.framework.TestSuite; | |||
| import org.apache.tools.ant.taskdefs.optional.rjunit.JUnitHelper; | |||
| import org.apache.tools.ant.taskdefs.optional.rjunit.formatter.Formatter; | |||
| import org.apache.tools.ant.taskdefs.optional.rjunit.formatter.PlainFormatter; | |||
| import org.apache.tools.ant.util.StringUtils; | |||
| /** | |||
| @@ -95,10 +102,11 @@ public class TestRunner implements TestListener { | |||
| /** port to connect to */ | |||
| private int port = -1; | |||
| /** handy debug flag */ | |||
| private boolean debug = false; | |||
| /** the list of test class names to run */ | |||
| private Vector testClassNames = new Vector(); | |||
| private final ArrayList testClassNames = new ArrayList(); | |||
| /** result of the current test */ | |||
| private TestResult testResult; | |||
| @@ -109,8 +117,14 @@ public class TestRunner implements TestListener { | |||
| /** writer to send message to the server */ | |||
| private Messenger messenger; | |||
| /** helpful formatter to debug events directly here */ | |||
| private final Formatter debugFormatter = new PlainFormatter(); | |||
| /** bean constructor */ | |||
| public TestRunner() { | |||
| Properties props = new Properties(); | |||
| props.setProperty("file", "rjunit-client-debug.log"); | |||
| debugFormatter.init(props); | |||
| } | |||
| /** | |||
| @@ -142,7 +156,7 @@ public class TestRunner implements TestListener { | |||
| * @param classname the class name of the test to run. | |||
| */ | |||
| public void addTestClassName(String classname) { | |||
| testClassNames.addElement(classname); | |||
| testClassNames.add(classname); | |||
| } | |||
| /** | |||
| @@ -265,16 +279,16 @@ public class TestRunner implements TestListener { | |||
| * @throws Exception a generic exception that can be thrown while | |||
| * instantiating a test case. | |||
| */ | |||
| protected Test[] getSuites() throws Exception { | |||
| protected Map getSuites() throws Exception { | |||
| final int count = testClassNames.size(); | |||
| log("Extracting testcases from " + count + " classnames..."); | |||
| final Vector suites = new Vector(count); | |||
| final Map suites = new HashMap(); | |||
| for (int i = 0; i < count; i++) { | |||
| String classname = (String) testClassNames.elementAt(i); | |||
| String classname = (String) testClassNames.get(i); | |||
| try { | |||
| Test test = JUnitHelper.getTest(null, classname); | |||
| if (test != null) { | |||
| suites.addElement(test); | |||
| suites.put(classname, test); | |||
| } | |||
| } catch (Exception e) { | |||
| // notify log error instead ? | |||
| @@ -283,9 +297,7 @@ public class TestRunner implements TestListener { | |||
| } | |||
| } | |||
| log("Extracted " + suites.size() + " testcases."); | |||
| Test[] array = new Test[suites.size()]; | |||
| suites.copyInto(array); | |||
| return array; | |||
| return suites; | |||
| } | |||
| /** | |||
| @@ -293,41 +305,75 @@ public class TestRunner implements TestListener { | |||
| */ | |||
| private void runTests() throws Exception { | |||
| Test[] suites = getSuites(); | |||
| Map suites = getSuites(); | |||
| // count all testMethods and inform TestRunListeners | |||
| int count = countTests(suites); | |||
| int count = countTests(suites.values()); | |||
| log("Total tests to run: " + count); | |||
| fireEvent(new TestRunEvent(id, TestRunEvent.RUN_STARTED)); | |||
| long startTime = System.currentTimeMillis(); | |||
| for (int i = 0; i < suites.length; i++) { | |||
| String name = suites[i].getClass().getName(); | |||
| if (suites[i] instanceof TestCase) { | |||
| suites[i] = new TestSuite(name); | |||
| TestRunEvent evt = new TestRunEvent(id, TestRunEvent.RUN_STARTED); | |||
| if (debug){ | |||
| debugFormatter.onRunStarted(evt); | |||
| } | |||
| fireEvent(evt); | |||
| TestSummary runSummary = new TestSummary(); | |||
| runSummary.start(testResult); | |||
| for (Iterator it = suites.entrySet().iterator(); it.hasNext(); ) { | |||
| Map.Entry entry = (Map.Entry)it.next(); | |||
| String name = (String)entry.getKey(); | |||
| Test test = (Test)entry.getValue(); | |||
| if (test instanceof TestCase) { | |||
| test = new TestSuite(name); | |||
| } | |||
| log("running suite: " + suites[i]); | |||
| fireEvent(new TestRunEvent(id, TestRunEvent.SUITE_STARTED, name)); | |||
| suites[i].run(testResult); | |||
| fireEvent(new TestRunEvent(id, TestRunEvent.SUITE_ENDED, name)); | |||
| runTest(test, name); | |||
| } | |||
| runSummary.stop(testResult); | |||
| // inform TestRunListeners of test end | |||
| long elapsedTime = System.currentTimeMillis() - startTime; | |||
| if (testResult == null || testResult.shouldStop()) { | |||
| fireEvent(new TestRunEvent(id, TestRunEvent.RUN_STOPPED, System.getProperties())); | |||
| } else { | |||
| fireEvent(new TestRunEvent(id, TestRunEvent.RUN_ENDED, System.getProperties())); | |||
| int type = (testResult == null || testResult.shouldStop()) ? | |||
| TestRunEvent.RUN_STOPPED : TestRunEvent.RUN_ENDED; | |||
| evt = new TestRunEvent(id, type, System.getProperties(), runSummary); | |||
| if (debug){ | |||
| debugFormatter.onRunEnded(evt); | |||
| } | |||
| log("Finished after " + elapsedTime + "ms"); | |||
| fireEvent(evt); | |||
| log("Finished after " + runSummary.elapsedTime() + "ms"); | |||
| shutDown(); | |||
| } | |||
| /** count the number of test methods in all tests */ | |||
| private final int countTests(Test[] tests) { | |||
| /** | |||
| * run a single suite and dispatch its results. | |||
| * @param test the instance of the testsuite to run. | |||
| * @param name the name of the testsuite (classname) | |||
| */ | |||
| private void runTest(Test test, String name){ | |||
| TestRunEvent evt = new TestRunEvent(id, TestRunEvent.SUITE_STARTED, name); | |||
| if (debug){ | |||
| debugFormatter.onSuiteStarted(evt); | |||
| } | |||
| fireEvent(evt); | |||
| TestSummary suiteSummary = new TestSummary(); | |||
| suiteSummary.start(testResult); | |||
| try { | |||
| test.run(testResult); | |||
| } finally { | |||
| suiteSummary.stop(testResult); | |||
| evt = new TestRunEvent(id, TestRunEvent.SUITE_ENDED, name, suiteSummary); | |||
| if (debug){ | |||
| debugFormatter.onSuiteEnded(evt); | |||
| } | |||
| fireEvent(evt); | |||
| } | |||
| } | |||
| /** | |||
| * count the number of test methods in all tests | |||
| */ | |||
| private final int countTests(Collection tests) { | |||
| int count = 0; | |||
| for (int i = 0; i < tests.length; i++) { | |||
| count = count + tests[i].countTestCases(); | |||
| for (Iterator it = tests.iterator(); it.hasNext(); ) { | |||
| Test test = (Test)it.next(); | |||
| count = count + test.countTestCases(); | |||
| } | |||
| return count; | |||
| } | |||
| @@ -383,14 +429,20 @@ public class TestRunner implements TestListener { | |||
| public void startTest(Test test) { | |||
| String testName = test.toString(); | |||
| log("starting test: " + test); | |||
| fireEvent(new TestRunEvent(id, TestRunEvent.TEST_STARTED, testName)); | |||
| TestRunEvent evt = new TestRunEvent(id, TestRunEvent.TEST_STARTED, testName); | |||
| if (debug){ | |||
| debugFormatter.onTestStarted(evt); | |||
| } | |||
| fireEvent(evt); | |||
| } | |||
| public void addError(Test test, Throwable t) { | |||
| log("Adding error for test: " + test); | |||
| String testName = test.toString(); | |||
| fireEvent(new TestRunEvent(id, TestRunEvent.TEST_ERROR, testName, t)); | |||
| TestRunEvent evt = new TestRunEvent(id, TestRunEvent.TEST_ERROR, testName, t); | |||
| if (debug){ | |||
| debugFormatter.onTestError(evt); | |||
| } | |||
| fireEvent(evt); | |||
| } | |||
| /** | |||
| @@ -406,15 +458,21 @@ public class TestRunner implements TestListener { | |||
| * @see addFailure(Test, AssertionFailedError) | |||
| */ | |||
| public void addFailure(Test test, Throwable t) { | |||
| log("Adding failure for test: " + test); | |||
| String testName = test.toString(); | |||
| fireEvent(new TestRunEvent(id, TestRunEvent.TEST_FAILURE, testName, t)); | |||
| TestRunEvent evt = new TestRunEvent(id, TestRunEvent.TEST_FAILURE, testName, t); | |||
| if (debug){ | |||
| debugFormatter.onTestFailure(evt); | |||
| } | |||
| fireEvent(evt); | |||
| } | |||
| public void endTest(Test test) { | |||
| log("Ending test: " + test); | |||
| String testName = test.toString(); | |||
| fireEvent(new TestRunEvent(id, TestRunEvent.TEST_ENDED, testName)); | |||
| TestRunEvent evt = new TestRunEvent(id, TestRunEvent.TEST_ENDED, testName); | |||
| if (debug){ | |||
| debugFormatter.onTestEnded(evt); | |||
| } | |||
| fireEvent(evt); | |||
| } | |||
| public void log(String msg) { | |||
| @@ -0,0 +1,177 @@ | |||
| /* | |||
| * The Apache Software License, Version 1.1 | |||
| * | |||
| * Copyright (c) 2002 The Apache Software Foundation. All rights | |||
| * reserved. | |||
| * | |||
| * Redistribution and use in source and binary forms, with or without | |||
| * modification, are permitted provided that the following conditions | |||
| * are met: | |||
| * | |||
| * 1. Redistributions of source code must retain the above copyright | |||
| * notice, this list of conditions and the following disclaimer. | |||
| * | |||
| * 2. Redistributions in binary form must reproduce the above copyright | |||
| * notice, this list of conditions and the following disclaimer in | |||
| * the documentation and/or other materials provided with the | |||
| * distribution. | |||
| * | |||
| * 3. The end-user documentation included with the redistribution, if | |||
| * any, must include the following acknowlegement: | |||
| * "This product includes software developed by the | |||
| * Apache Software Foundation (http://www.apache.org/)." | |||
| * Alternately, this acknowlegement may appear in the software itself, | |||
| * if and wherever such third-party acknowlegements normally appear. | |||
| * | |||
| * 4. The names "The Jakarta Project", "Ant", and "Apache Software | |||
| * Foundation" must not be used to endorse or promote products derived | |||
| * from this software without prior written permission. For written | |||
| * permission, please contact apache@apache.org. | |||
| * | |||
| * 5. Products derived from this software may not be called "Apache" | |||
| * nor may "Apache" appear in their names without prior written | |||
| * permission of the Apache Group. | |||
| * | |||
| * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED | |||
| * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |||
| * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | |||
| * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR | |||
| * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | |||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | |||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF | |||
| * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | |||
| * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, | |||
| * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT | |||
| * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF | |||
| * SUCH DAMAGE. | |||
| * ==================================================================== | |||
| * | |||
| * This software consists of voluntary contributions made by many | |||
| * individuals on behalf of the Apache Software Foundation. For more | |||
| * information on the Apache Software Foundation, please see | |||
| * <http://www.apache.org/>. | |||
| */ | |||
| package org.apache.tools.ant.taskdefs.optional.rjunit.remote; | |||
| import java.io.Serializable; | |||
| import junit.framework.AssertionFailedError; | |||
| import junit.framework.Test; | |||
| import junit.framework.TestListener; | |||
| import junit.framework.TestResult; | |||
| /** | |||
| * A helpful test summary that is somewhat similar to <tt>TestResult</tt>. | |||
| * Here the difference is that this test summary should register to | |||
| * the test result the time you wan to collect information. | |||
| * | |||
| * @author <a href="mailto:sbailliez@apache.org">Stephane Bailliez</a> | |||
| */ | |||
| public final class TestSummary implements Serializable, TestListener { | |||
| /** time elapsed during tests run in ms */ | |||
| private long elapsedTime; | |||
| /** number of errors */ | |||
| private int errorCount; | |||
| /** number of successes */ | |||
| private int successCount; | |||
| /** number of failures */ | |||
| private int failureCount; | |||
| /** number of runs */ | |||
| private int runCount; | |||
| private transient String toString; | |||
| /** bean constructor */ | |||
| public TestSummary() { | |||
| } | |||
| /** | |||
| * @return the number of errors that occurred in this test. | |||
| */ | |||
| public int errorCount() { | |||
| return errorCount; | |||
| } | |||
| /** | |||
| * @return the number of successes that occurred in this test. | |||
| */ | |||
| public int successCount() { | |||
| return successCount; | |||
| } | |||
| /** | |||
| * @return the number of failures that occurred in this test. | |||
| */ | |||
| public int failureCount() { | |||
| return failureCount; | |||
| } | |||
| /** | |||
| * @return the number of runs that occurred in this test. | |||
| * a run is the sum of failures + errors + successes. | |||
| */ | |||
| public int runCount() { | |||
| return runCount; | |||
| } | |||
| /** | |||
| * @return the elapsed time in ms | |||
| */ | |||
| public long elapsedTime() { | |||
| return elapsedTime; | |||
| } | |||
| // | |||
| /** | |||
| * register to the <tt>TestResult</tt> and starts the time counter. | |||
| * @param result the instance to register to. | |||
| * @see #stop() | |||
| */ | |||
| public void start(TestResult result){ | |||
| elapsedTime = System.currentTimeMillis(); | |||
| result.addListener(this); | |||
| } | |||
| /** | |||
| * unregister from the <tt>TestResult</tt> and stops the time counter. | |||
| * @param result the instance to unregister from. | |||
| * @see #start() | |||
| */ | |||
| public void stop(TestResult result){ | |||
| elapsedTime = System.currentTimeMillis() - elapsedTime; | |||
| result.removeListener(this); | |||
| } | |||
| // test listener implementation | |||
| public void addError(Test test, Throwable throwable) { | |||
| errorCount++; | |||
| } | |||
| public void addFailure(Test test, AssertionFailedError error) { | |||
| failureCount++; | |||
| } | |||
| public void endTest(Test test) { | |||
| successCount++; | |||
| } | |||
| public void startTest(Test test) { | |||
| runCount++; | |||
| } | |||
| public String toString(){ | |||
| StringBuffer buf = new StringBuffer(); | |||
| buf.append("run: ").append(runCount); | |||
| buf.append(" success: ").append(successCount); | |||
| buf.append(" failures: ").append(failureCount); | |||
| buf.append(" errors: ").append(errorCount); | |||
| buf.append(" elapsed: ").append(elapsedTime); | |||
| return buf.toString(); | |||
| } | |||
| } | |||