1 package org.junit.tests.running.classes;
2
3 import static org.hamcrest.CoreMatchers.equalTo;
4 import static org.hamcrest.CoreMatchers.is;
5 import static org.junit.Assert.assertEquals;
6 import static org.junit.Assert.assertThat;
7
8 import java.util.List;
9
10 import org.hamcrest.Matcher;
11 import org.hamcrest.TypeSafeMatcher;
12 import org.junit.Assert;
13 import org.junit.BeforeClass;
14 import org.junit.Ignore;
15 import org.junit.Test;
16 import org.junit.internal.AssumptionViolatedException;
17 import org.junit.runner.Description;
18 import org.junit.runner.JUnitCore;
19 import org.junit.runner.Request;
20 import org.junit.runner.Result;
21 import org.junit.runner.manipulation.Filter;
22 import org.junit.runner.notification.Failure;
23 import org.junit.runner.notification.RunListener;
24 import org.junit.runner.notification.RunNotifier;
25 import org.junit.runners.BlockJUnit4ClassRunner;
26 import org.junit.runners.ParentRunner;
27 import org.junit.runners.model.InitializationError;
28 import org.junit.runners.model.RunnerScheduler;
29 import org.junit.tests.experimental.rules.RuleMemberValidatorTest.TestWithNonStaticClassRule;
30 import org.junit.tests.experimental.rules.RuleMemberValidatorTest.TestWithProtectedClassRule;
31
32 public class ParentRunnerTest {
33 public static String log = "";
34
35 public static class FruitTest {
36 @Test
37 public void apple() {
38 log += "apple ";
39 }
40
41 @Test
42 public void Banana() {
43 log += "banana ";
44 }
45 }
46
47 @Test
48 public void useChildHarvester() throws InitializationError {
49 log = "";
50 ParentRunner<?> runner = new BlockJUnit4ClassRunner(FruitTest.class);
51 runner.setScheduler(new RunnerScheduler() {
52 public void schedule(Runnable childStatement) {
53 log += "before ";
54 childStatement.run();
55 log += "after ";
56 }
57
58 public void finished() {
59 log += "afterAll ";
60 }
61 });
62
63 runner.run(new RunNotifier());
64 assertEquals("before apple after before banana after afterAll ", log);
65 }
66
67 @Test
68 public void testMultipleFilters() throws Exception {
69 JUnitCore junitCore = new JUnitCore();
70 Request request = Request.aClass(ExampleTest.class);
71 Request requestFiltered = request.filterWith(new Exclude("test1"));
72 Request requestFilteredFiltered = requestFiltered
73 .filterWith(new Exclude("test2"));
74 Result result = junitCore.run(requestFilteredFiltered);
75 assertThat(result.getFailures(), isEmpty());
76 assertEquals(1, result.getRunCount());
77 }
78
79 private Matcher<List<?>> isEmpty() {
80 return new TypeSafeMatcher<List<?>>() {
81 public void describeTo(org.hamcrest.Description description) {
82 description.appendText("is empty");
83 }
84
85 @Override
86 public boolean matchesSafely(List<?> item) {
87 return item.size() == 0;
88 }
89 };
90 }
91
92 private static class Exclude extends Filter {
93 private final String methodName;
94
95 public Exclude(String methodName) {
96 this.methodName = methodName;
97 }
98
99 @Override
100 public boolean shouldRun(Description description) {
101 return !description.getMethodName().equals(methodName);
102 }
103
104 @Override
105 public String describe() {
106 return "filter method name: " + methodName;
107 }
108 }
109
110 public static class ExampleTest {
111 @Test
112 public void test1() throws Exception {
113 }
114
115 @Test
116 public void test2() throws Exception {
117 }
118
119 @Test
120 public void test3() throws Exception {
121 }
122 }
123
124 @Test
125 public void failWithHelpfulMessageForProtectedClassRule() {
126 assertClassHasFailureMessage(TestWithProtectedClassRule.class,
127 "The @ClassRule 'temporaryFolder' must be public.");
128 }
129
130 @Test
131 public void failWithHelpfulMessageForNonStaticClassRule() {
132 assertClassHasFailureMessage(TestWithNonStaticClassRule.class,
133 "The @ClassRule 'temporaryFolder' must be static.");
134 }
135
136 static class NonPublicTestClass {
137 public NonPublicTestClass() {
138 }
139 }
140
141 @Test
142 public void cannotBeCreatedWithNonPublicTestClass() {
143 assertClassHasFailureMessage(
144 NonPublicTestClass.class,
145 "The class org.junit.tests.running.classes.ParentRunnerTest$NonPublicTestClass is not public.");
146 }
147
148 private void assertClassHasFailureMessage(Class<?> klass, String message) {
149 JUnitCore junitCore = new JUnitCore();
150 Request request = Request.aClass(klass);
151 Result result = junitCore.run(request);
152 assertThat(result.getFailureCount(), is(2));
153 assertThat(result.getFailures().get(0).getMessage(),
154 is(equalTo(message)));
155 }
156
157 public static class AssertionErrorAtParentLevelTest {
158 @BeforeClass
159 public static void beforeClass() throws Throwable {
160 throw new AssertionError("Thrown from @BeforeClass");
161 }
162
163 @Test
164 public void test() {}
165 }
166
167 @Test
168 public void assertionErrorAtParentLevelTest() throws InitializationError {
169 CountingRunListener countingRunListener = runTestWithParentRunner(AssertionErrorAtParentLevelTest.class);
170 Assert.assertEquals(0, countingRunListener.testStarted);
171 Assert.assertEquals(0, countingRunListener.testFinished);
172 Assert.assertEquals(1, countingRunListener.testFailure);
173 Assert.assertEquals(0, countingRunListener.testAssumptionFailure);
174 Assert.assertEquals(0, countingRunListener.testIgnored);
175 }
176
177 public static class AssumptionViolatedAtParentLevelTest {
178 @BeforeClass
179 public static void beforeClass() {
180 throw new AssumptionViolatedException("Thrown from @BeforeClass");
181 }
182
183 @Test
184 public void test() {}
185 }
186
187 @Test
188 public void assumptionViolatedAtParentLevel() throws InitializationError {
189 CountingRunListener countingRunListener = runTestWithParentRunner(AssumptionViolatedAtParentLevelTest.class);
190 Assert.assertEquals(0, countingRunListener.testStarted);
191 Assert.assertEquals(0, countingRunListener.testFinished);
192 Assert.assertEquals(0, countingRunListener.testFailure);
193 Assert.assertEquals(1, countingRunListener.testAssumptionFailure);
194 Assert.assertEquals(0, countingRunListener.testIgnored);
195 }
196
197 public static class TestTest {
198 @Test
199 public void pass() {}
200
201 @Test
202 public void fail() {
203 throw new AssertionError("Thrown from @Test");
204 }
205
206 @Ignore
207 @Test
208 public void ignore() {}
209
210 @Test
211 public void assumptionFail() {
212 throw new AssumptionViolatedException("Thrown from @Test");
213 }
214 }
215
216 @Test
217 public void parentRunnerTestMethods() throws InitializationError {
218 CountingRunListener countingRunListener = runTestWithParentRunner(TestTest.class);
219 Assert.assertEquals(3, countingRunListener.testStarted);
220 Assert.assertEquals(3, countingRunListener.testFinished);
221 Assert.assertEquals(1, countingRunListener.testFailure);
222 Assert.assertEquals(1, countingRunListener.testAssumptionFailure);
223 Assert.assertEquals(1, countingRunListener.testIgnored);
224 }
225
226 private CountingRunListener runTestWithParentRunner(Class<?> testClass) throws InitializationError {
227 CountingRunListener listener = new CountingRunListener();
228 RunNotifier runNotifier = new RunNotifier();
229 runNotifier.addListener(listener);
230 ParentRunner runner = new BlockJUnit4ClassRunner(testClass);
231 runner.run(runNotifier);
232 return listener;
233 }
234
235 private static class CountingRunListener extends RunListener {
236 private int testStarted = 0;
237 private int testFinished = 0;
238 private int testFailure = 0;
239 private int testAssumptionFailure = 0;
240 private int testIgnored = 0;
241
242 @Override
243 public void testStarted(Description description) throws Exception {
244 testStarted++;
245 }
246
247 @Override
248 public void testFinished(Description description) throws Exception {
249 testFinished++;
250 }
251
252 @Override
253 public void testFailure(Failure failure) throws Exception {
254 testFailure++;
255 }
256
257 @Override
258 public void testAssumptionFailure(Failure failure) {
259 testAssumptionFailure++;
260 }
261
262 @Override
263 public void testIgnored(Description description) throws Exception {
264 testIgnored++;
265 }
266 }
267 }