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