1 package org.junit.runner; 2 3 import java.io.IOException; 4 import java.io.ObjectInputStream; 5 import java.io.ObjectOutputStream; 6 import java.io.ObjectStreamClass; 7 import java.io.ObjectStreamField; 8 import java.io.Serializable; 9 import java.util.ArrayList; 10 import java.util.Collections; 11 import java.util.List; 12 import java.util.concurrent.CopyOnWriteArrayList; 13 import java.util.concurrent.atomic.AtomicInteger; 14 import java.util.concurrent.atomic.AtomicLong; 15 16 import org.junit.runner.notification.Failure; 17 import org.junit.runner.notification.RunListener; 18 19 /** 20 * A <code>Result</code> collects and summarizes information from running multiple tests. 21 * All tests are counted -- additional information is collected from tests that fail. 22 * 23 * @since 4.0 24 */ 25 public class Result implements Serializable { 26 private static final long serialVersionUID = 1L; 27 private static final ObjectStreamField[] serialPersistentFields = 28 ObjectStreamClass.lookup(SerializedForm.class).getFields(); 29 private final AtomicInteger count; 30 private final AtomicInteger ignoreCount; 31 private final AtomicInteger assumptionFailureCount; 32 private final CopyOnWriteArrayList<Failure> failures; 33 private final AtomicLong runTime; 34 private final AtomicLong startTime; 35 36 /** Only set during deserialization process. */ 37 private SerializedForm serializedForm; 38 Result()39 public Result() { 40 count = new AtomicInteger(); 41 ignoreCount = new AtomicInteger(); 42 assumptionFailureCount = new AtomicInteger(); 43 failures = new CopyOnWriteArrayList<Failure>(); 44 runTime = new AtomicLong(); 45 startTime = new AtomicLong(); 46 } 47 Result(SerializedForm serializedForm)48 private Result(SerializedForm serializedForm) { 49 count = serializedForm.fCount; 50 ignoreCount = serializedForm.fIgnoreCount; 51 assumptionFailureCount = serializedForm.assumptionFailureCount; 52 failures = new CopyOnWriteArrayList<Failure>(serializedForm.fFailures); 53 runTime = new AtomicLong(serializedForm.fRunTime); 54 startTime = new AtomicLong(serializedForm.fStartTime); 55 } 56 57 /** 58 * Returns the number of tests run 59 */ getRunCount()60 public int getRunCount() { 61 return count.get(); 62 } 63 64 /** 65 * Returns the number of tests that failed during the run 66 */ getFailureCount()67 public int getFailureCount() { 68 return failures.size(); 69 } 70 71 /** 72 * Returns the number of milliseconds it took to run the entire suite to run 73 */ getRunTime()74 public long getRunTime() { 75 return runTime.get(); 76 } 77 78 /** 79 * Returns the {@link Failure}s describing tests that failed and the problems they encountered 80 */ getFailures()81 public List<Failure> getFailures() { 82 return failures; 83 } 84 85 /** 86 * @return the number of tests ignored during the run 87 */ getIgnoreCount()88 public int getIgnoreCount() { 89 return ignoreCount.get(); 90 } 91 92 /** 93 * Returns the number of tests skipped because of an assumption failure 94 * 95 * @throws UnsupportedOperationException if the result was serialized in a version before JUnit 4.13 96 * @since 4.13 97 */ getAssumptionFailureCount()98 public int getAssumptionFailureCount() { 99 if (assumptionFailureCount == null) { 100 throw new UnsupportedOperationException( 101 "Result was serialized from a version of JUnit that doesn't support this method"); 102 } 103 return assumptionFailureCount.get(); 104 } 105 106 /** 107 * @return <code>true</code> if all tests succeeded 108 */ wasSuccessful()109 public boolean wasSuccessful() { 110 return getFailureCount() == 0; 111 } 112 writeObject(ObjectOutputStream s)113 private void writeObject(ObjectOutputStream s) throws IOException { 114 SerializedForm serializedForm = new SerializedForm(this); 115 serializedForm.serialize(s); 116 } 117 readObject(ObjectInputStream s)118 private void readObject(ObjectInputStream s) 119 throws ClassNotFoundException, IOException { 120 serializedForm = SerializedForm.deserialize(s); 121 } 122 readResolve()123 private Object readResolve() { 124 return new Result(serializedForm); 125 } 126 127 @RunListener.ThreadSafe 128 private class Listener extends RunListener { 129 @Override testRunStarted(Description description)130 public void testRunStarted(Description description) throws Exception { 131 startTime.set(System.currentTimeMillis()); 132 } 133 134 @Override testRunFinished(Result result)135 public void testRunFinished(Result result) throws Exception { 136 long endTime = System.currentTimeMillis(); 137 runTime.addAndGet(endTime - startTime.get()); 138 } 139 140 @Override testFinished(Description description)141 public void testFinished(Description description) throws Exception { 142 count.getAndIncrement(); 143 } 144 145 @Override testFailure(Failure failure)146 public void testFailure(Failure failure) throws Exception { 147 failures.add(failure); 148 } 149 150 @Override testIgnored(Description description)151 public void testIgnored(Description description) throws Exception { 152 ignoreCount.getAndIncrement(); 153 } 154 155 @Override testAssumptionFailure(Failure failure)156 public void testAssumptionFailure(Failure failure) { 157 assumptionFailureCount.getAndIncrement(); 158 } 159 } 160 161 /** 162 * Internal use only. 163 */ createListener()164 public RunListener createListener() { 165 return new Listener(); 166 } 167 168 /** 169 * Represents the serialized output of {@code Result}. The fields on this 170 * class match the files that {@code Result} had in JUnit 4.11. 171 */ 172 private static class SerializedForm implements Serializable { 173 private static final long serialVersionUID = 1L; 174 private final AtomicInteger fCount; 175 private final AtomicInteger fIgnoreCount; 176 private final AtomicInteger assumptionFailureCount; 177 private final List<Failure> fFailures; 178 private final long fRunTime; 179 private final long fStartTime; 180 SerializedForm(Result result)181 public SerializedForm(Result result) { 182 fCount = result.count; 183 fIgnoreCount = result.ignoreCount; 184 assumptionFailureCount = result.assumptionFailureCount; 185 fFailures = Collections.synchronizedList(new ArrayList<Failure>(result.failures)); 186 fRunTime = result.runTime.longValue(); 187 fStartTime = result.startTime.longValue(); 188 } 189 190 @SuppressWarnings("unchecked") SerializedForm(ObjectInputStream.GetField fields)191 private SerializedForm(ObjectInputStream.GetField fields) throws IOException { 192 fCount = (AtomicInteger) fields.get("fCount", null); 193 fIgnoreCount = (AtomicInteger) fields.get("fIgnoreCount", null); 194 assumptionFailureCount = (AtomicInteger) fields.get("assumptionFailureCount", null); 195 fFailures = (List<Failure>) fields.get("fFailures", null); 196 fRunTime = fields.get("fRunTime", 0L); 197 fStartTime = fields.get("fStartTime", 0L); 198 } 199 serialize(ObjectOutputStream s)200 public void serialize(ObjectOutputStream s) throws IOException { 201 ObjectOutputStream.PutField fields = s.putFields(); 202 fields.put("fCount", fCount); 203 fields.put("fIgnoreCount", fIgnoreCount); 204 fields.put("fFailures", fFailures); 205 fields.put("fRunTime", fRunTime); 206 fields.put("fStartTime", fStartTime); 207 fields.put("assumptionFailureCount", assumptionFailureCount); 208 s.writeFields(); 209 } 210 deserialize(ObjectInputStream s)211 public static SerializedForm deserialize(ObjectInputStream s) 212 throws ClassNotFoundException, IOException { 213 ObjectInputStream.GetField fields = s.readFields(); 214 return new SerializedForm(fields); 215 } 216 } 217 } 218