TestResult.java revision 2ad60cfc28e14ee8f0bb038720836a4696c478ad
1package junit.framework;
2
3import java.util.Vector;
4import java.util.Enumeration;
5
6/**
7 * A <code>TestResult</code> collects the results of executing
8 * a test case. It is an instance of the Collecting Parameter pattern.
9 * The test framework distinguishes between <i>failures</i> and <i>errors</i>.
10 * A failure is anticipated and checked for with assertions. Errors are
11 * unanticipated problems like an <code>ArrayIndexOutOfBoundsException</code>.
12 *
13 * @see Test
14 */
15public class TestResult extends Object {
16    protected Vector fFailures;
17    protected Vector fErrors;
18    protected Vector fListeners;
19    protected int fRunTests;
20    private boolean fStop;
21
22    public TestResult() {
23        fFailures= new Vector();
24        fErrors= new Vector();
25        fListeners= new Vector();
26        fRunTests= 0;
27        fStop= false;
28    }
29    /**
30     * Adds an error to the list of errors. The passed in exception
31     * caused the error.
32     */
33    public synchronized void addError(Test test, Throwable t) {
34        fErrors.addElement(new TestFailure(test, t));
35        for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
36            ((TestListener)e.nextElement()).addError(test, t);
37        }
38    }
39    /**
40     * Adds a failure to the list of failures. The passed in exception
41     * caused the failure.
42     */
43    public synchronized void addFailure(Test test, AssertionFailedError t) {
44        fFailures.addElement(new TestFailure(test, t));
45        for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
46            ((TestListener)e.nextElement()).addFailure(test, t);
47        }
48    }
49    /**
50     * Registers a TestListener
51     */
52    public synchronized void addListener(TestListener listener) {
53        fListeners.addElement(listener);
54    }
55    /**
56     * Unregisters a TestListener
57     */
58    public synchronized void removeListener(TestListener listener) {
59        fListeners.removeElement(listener);
60    }
61    /**
62     * Returns a copy of the listeners.
63     */
64    private synchronized Vector cloneListeners() {
65        return (Vector)fListeners.clone();
66    }
67    /**
68     * Informs the result that a test was completed.
69     */
70    public void endTest(Test test) {
71        for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
72            ((TestListener)e.nextElement()).endTest(test);
73        }
74    }
75    /**
76     * Gets the number of detected errors.
77     */
78    public synchronized int errorCount() {
79        return fErrors.size();
80    }
81    /**
82     * Returns an Enumeration for the errors
83     */
84    public synchronized Enumeration errors() {
85        return fErrors.elements();
86    }
87    /**
88     * Gets the number of detected failures.
89     */
90    public synchronized int failureCount() {
91        return fFailures.size();
92    }
93    /**
94     * Returns an Enumeration for the failures
95     */
96    public synchronized Enumeration failures() {
97        return fFailures.elements();
98    }
99    /**
100     * Runs a TestCase.
101     */
102    protected void run(final TestCase test) {
103        startTest(test);
104        Protectable p= new Protectable() {
105            public void protect() throws Throwable {
106                test.runBare();
107            }
108        };
109        runProtected(test, p);
110
111        endTest(test);
112    }
113    /**
114     * Gets the number of run tests.
115     */
116    public synchronized int runCount() {
117        return fRunTests;
118    }
119    /**
120     * Runs a TestCase.
121     */
122    public void runProtected(final Test test, Protectable p) {
123        try {
124            p.protect();
125        }
126        catch (AssertionFailedError e) {
127            addFailure(test, e);
128        }
129        catch (ThreadDeath e) { // don't catch ThreadDeath by accident
130            throw e;
131        }
132        catch (Throwable e) {
133            addError(test, e);
134        }
135    }
136    /**
137     * Checks whether the test run should stop
138     */
139    public synchronized boolean shouldStop() {
140        return fStop;
141    }
142    /**
143     * Informs the result that a test will be started.
144     */
145    public void startTest(Test test) {
146        final int count= test.countTestCases();
147        synchronized(this) {
148            fRunTests+= count;
149        }
150        for (Enumeration e= cloneListeners().elements(); e.hasMoreElements(); ) {
151            ((TestListener)e.nextElement()).startTest(test);
152        }
153    }
154    /**
155     * Marks that the test run should stop.
156     */
157    public synchronized void stop() {
158        fStop= true;
159    }
160    /**
161     * Returns whether the entire test was successful or not.
162     */
163    public synchronized boolean wasSuccessful() {
164        return failureCount() == 0 && errorCount() == 0;
165    }
166}
167