001 package org.junit.rules; 002 003 import java.util.ArrayList; 004 import java.util.List; 005 006 import org.junit.AssumptionViolatedException; 007 import org.junit.runner.Description; 008 import org.junit.runners.model.MultipleFailureException; 009 import org.junit.runners.model.Statement; 010 011 /** 012 * TestWatcher is a base class for Rules that take note of the testing 013 * action, without modifying it. For example, this class will keep a log of each 014 * passing and failing test: 015 * 016 * <pre> 017 * public static class WatchmanTest { 018 * private static String watchedLog; 019 * 020 * @Rule 021 * public TestWatcher watchman= new TestWatcher() { 022 * @Override 023 * protected void failed(Throwable e, Description description) { 024 * watchedLog+= description + "\n"; 025 * } 026 * 027 * @Override 028 * protected void succeeded(Description description) { 029 * watchedLog+= description + " " + "success!\n"; 030 * } 031 * }; 032 * 033 * @Test 034 * public void fails() { 035 * fail(); 036 * } 037 * 038 * @Test 039 * public void succeeds() { 040 * } 041 * } 042 * </pre> 043 * 044 * @since 4.9 045 */ 046 public abstract class TestWatcher implements TestRule { 047 public Statement apply(final Statement base, final Description description) { 048 return new Statement() { 049 @Override 050 public void evaluate() throws Throwable { 051 List<Throwable> errors = new ArrayList<Throwable>(); 052 053 startingQuietly(description, errors); 054 try { 055 base.evaluate(); 056 succeededQuietly(description, errors); 057 } catch (@SuppressWarnings("deprecation") org.junit.internal.AssumptionViolatedException e) { 058 errors.add(e); 059 skippedQuietly(e, description, errors); 060 } catch (Throwable e) { 061 errors.add(e); 062 failedQuietly(e, description, errors); 063 } finally { 064 finishedQuietly(description, errors); 065 } 066 067 MultipleFailureException.assertEmpty(errors); 068 } 069 }; 070 } 071 072 private void succeededQuietly(Description description, 073 List<Throwable> errors) { 074 try { 075 succeeded(description); 076 } catch (Throwable e) { 077 errors.add(e); 078 } 079 } 080 081 private void failedQuietly(Throwable e, Description description, 082 List<Throwable> errors) { 083 try { 084 failed(e, description); 085 } catch (Throwable e1) { 086 errors.add(e1); 087 } 088 } 089 090 @SuppressWarnings("deprecation") 091 private void skippedQuietly( 092 org.junit.internal.AssumptionViolatedException e, Description description, 093 List<Throwable> errors) { 094 try { 095 if (e instanceof AssumptionViolatedException) { 096 skipped((AssumptionViolatedException) e, description); 097 } else { 098 skipped(e, description); 099 } 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 }