TestResult.java revision 58a8b0aba2dec5695628a2bf25a3fae42c2c3533
1package junit.framework;
2
3import java.util.Enumeration;
4import java.util.Vector;
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}