1
1
package org .junit .runner .notification ;
2
2
3
+ import java .lang .annotation .Documented ;
4
+ import java .lang .annotation .ElementType ;
5
+ import java .lang .annotation .Retention ;
6
+ import java .lang .annotation .RetentionPolicy ;
7
+ import java .lang .annotation .Target ;
8
+
3
9
import org .junit .internal .AssumptionViolatedException ;
4
10
import org .junit .runner .Description ;
5
11
import org .junit .runner .Result ;
6
12
7
13
/**
8
- * <p>If you need to respond to the events during a test run, extend <code>RunListener</code>
9
- * and override the appropriate methods. If a listener throws an exception while processing a
10
- * test event, it will be removed for the remainder of the test run.</p>
14
+ * Register an instance of this class with {@link RunNotifier} to be notified
15
+ * of events that occur during a test run. All of the methods in this class
16
+ * are abstract and have no implementation; override one or more methods to
17
+ * receive events.
11
18
*
12
19
* <p>For example, suppose you have a <code>Cowbell</code>
13
20
* class that you want to make a noise whenever a test fails. You could write:
18
25
* }
19
26
* }
20
27
* </pre>
21
- * </p>
22
28
*
23
29
* <p>To invoke your listener, you need to run your tests through <code>JUnitCore</code>.
24
30
* <pre>
28
34
* core.run(MyTestClass.class);
29
35
* }
30
36
* </pre>
31
- * </p>
37
+ *
38
+ * <p>If a listener throws an exception for a test event, the other listeners will
39
+ * have their {@link RunListener#testFailure(Failure)} called with a {@code Description}
40
+ * of {@link Description#TEST_MECHANISM} to indicate the failure.
41
+ *
42
+ * <p>By default, JUnit will synchronize calls to your listener. If your listener
43
+ * is thread-safe and you want to allow JUnit to call your listener from
44
+ * multiple threads when tests are run in parallel, you can annotate your
45
+ * test class with {@link RunListener.ThreadSafe}.
46
+ *
47
+ * <p>Listener methods will be called from the same thread as is running
48
+ * the test, unless otherwise indicated by the method Javadoc
32
49
*
33
50
* @see org.junit.runner.JUnitCore
34
51
* @since 4.0
35
52
*/
36
53
public class RunListener {
37
54
38
55
/**
39
- * Called before any tests have been run.
56
+ * Called before any tests have been run. This may not necessarily
57
+ * be called by the same thread as started the test run.
40
58
*
41
59
* @param description describes the tests to be run
42
60
*/
43
61
public void testRunStarted (Description description ) throws Exception {
44
62
}
45
63
46
64
/**
47
- * Called when all tests have finished
65
+ * Called when all tests have finished. This may not necessarily
66
+ * be called by the same thread as started the test run.
48
67
*
49
68
* @param result the summary of the test run, including all the tests that failed
50
69
*/
@@ -69,7 +88,17 @@ public void testFinished(Description description) throws Exception {
69
88
}
70
89
71
90
/**
72
- * Called when an atomic test fails.
91
+ * Called when an atomic test fails, or when a listener throws an exception.
92
+ *
93
+ * <p>In the case of a failure of an atomic test, this method will be called
94
+ * with the same {@code Description} passed to
95
+ * {@link #testStarted(Description)}, from the same thread that called
96
+ * {@link #testStarted(Description)}.
97
+ *
98
+ * <p>In the case of a listener throwing an exception, this will be called with
99
+ * a {@code Description} of {@link Description#TEST_MECHANISM}. This call
100
+ * may or may not be called in the same thread as the failing listener was
101
+ * called
73
102
*
74
103
* @param failure describes the test that failed and the exception that was thrown
75
104
*/
@@ -94,6 +123,20 @@ public void testAssumptionFailure(Failure failure) {
94
123
*/
95
124
public void testIgnored (Description description ) throws Exception {
96
125
}
97
- }
98
126
99
127
128
+ /**
129
+ * Indicates a {@code RunListener} that can have its methods called
130
+ * concurrently. This implies that the class is thread-safe (i.e. no set of
131
+ * listener calls can put the listener into an invalid state, even if those
132
+ * listener calls are being made by multiple threads without
133
+ * synchronization).
134
+ *
135
+ * @since 4.12
136
+ */
137
+ @ Documented
138
+ @ Target (ElementType .TYPE )
139
+ @ Retention (RetentionPolicy .RUNTIME )
140
+ public @interface ThreadSafe {
141
+ }
142
+ }
0 commit comments