1 package org.junit.rules; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 import org.junit.AssumptionViolatedException; 7 import org.junit.runner.Description; 8 import org.junit.runners.model.MultipleFailureException; 9 import org.junit.runners.model.Statement; 10 11 /** 12 * TestWatcher is a base class for Rules that take note of the testing 13 * action, without modifying it. For example, this class will keep a log of each 14 * passing and failing test: 15 * 16 * <pre> 17 * public static class WatchmanTest { 18 * private static String watchedLog; 19 * 20 * @Rule 21 * public TestWatcher watchman= new TestWatcher() { 22 * @Override 23 * protected void failed(Throwable e, Description description) { 24 * watchedLog+= description + "\n"; 25 * } 26 * 27 * @Override 28 * protected void succeeded(Description description) { 29 * watchedLog+= description + " " + "success!\n"; 30 * } 31 * }; 32 * 33 * @Test 34 * public void fails() { 35 * fail(); 36 * } 37 * 38 * @Test 39 * public void succeeds() { 40 * } 41 * } 42 * </pre> 43 * 44 * @since 4.9 45 */ 46 public abstract class TestWatcher implements TestRule { apply(final Statement base, final Description description)47 public Statement apply(final Statement base, final Description description) { 48 return new Statement() { 49 @Override 50 public void evaluate() throws Throwable { 51 List<Throwable> errors = new ArrayList<Throwable>(); 52 53 startingQuietly(description, errors); 54 try { 55 base.evaluate(); 56 succeededQuietly(description, errors); 57 } catch (@SuppressWarnings("deprecation") org.junit.internal.AssumptionViolatedException e) { 58 errors.add(e); 59 skippedQuietly(e, description, errors); 60 } catch (Throwable e) { 61 errors.add(e); 62 failedQuietly(e, description, errors); 63 } finally { 64 finishedQuietly(description, errors); 65 } 66 67 MultipleFailureException.assertEmpty(errors); 68 } 69 }; 70 } 71 72 private void succeededQuietly(Description description, 73 List<Throwable> errors) { 74 try { 75 succeeded(description); 76 } catch (Throwable e) { 77 errors.add(e); 78 } 79 } 80 81 private void failedQuietly(Throwable e, Description description, 82 List<Throwable> errors) { 83 try { 84 failed(e, description); 85 } catch (Throwable e1) { 86 errors.add(e1); 87 } 88 } 89 90 @SuppressWarnings("deprecation") 91 private void skippedQuietly( 92 org.junit.internal.AssumptionViolatedException e, Description description, 93 List<Throwable> errors) { 94 try { 95 if (e instanceof AssumptionViolatedException) { 96 skipped((AssumptionViolatedException) e, description); 97 } else { 98 skipped(e, description); 99 } 100 } catch (Throwable e1) { 101 errors.add(e1); 102 } 103 } 104 105 private void startingQuietly(Description description, 106 List<Throwable> errors) { 107 try { 108 starting(description); 109 } catch (Throwable e) { 110 errors.add(e); 111 } 112 } 113 114 private void finishedQuietly(Description description, 115 List<Throwable> errors) { 116 try { 117 finished(description); 118 } catch (Throwable e) { 119 errors.add(e); 120 } 121 } 122 123 /** 124 * Invoked when a test succeeds 125 */ 126 protected void succeeded(Description description) { 127 } 128 129 /** 130 * Invoked when a test fails 131 */ 132 protected void failed(Throwable e, Description description) { 133 } 134 135 /** 136 * Invoked when a test is skipped due to a failed assumption. 137 */ 138 @SuppressWarnings("deprecation") 139 protected void skipped(AssumptionViolatedException e, Description description) { 140 // For backwards compatibility with JUnit 4.11 and earlier, call the legacy version 141 org.junit.internal.AssumptionViolatedException asInternalException = e; 142 skipped(asInternalException, description); 143 } 144 145 /** 146 * Invoked when a test is skipped due to a failed assumption. 147 * 148 * @deprecated use {@link #skipped(AssumptionViolatedException, Description)} 149 */ 150 @Deprecated 151 protected void skipped( 152 org.junit.internal.AssumptionViolatedException e, Description description) { 153 } 154 155 /** 156 * Invoked when a test is about to start 157 */ 158 protected void starting(Description description) { 159 } 160 161 /** 162 * Invoked when a test method finishes (whether passing or failing) 163 */ 164 protected void finished(Description description) { 165 } 166 } 167