1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.maven.surefire.junitplatform;
20
21 import java.lang.reflect.Method;
22 import java.util.Map;
23 import java.util.Optional;
24
25 import org.apache.maven.surefire.api.report.ReportEntry;
26 import org.apache.maven.surefire.api.report.SimpleReportEntry;
27 import org.apache.maven.surefire.api.report.StackTraceWriter;
28 import org.apache.maven.surefire.api.report.TestOutputReportEntry;
29 import org.apache.maven.surefire.api.report.TestReportListener;
30 import org.apache.maven.surefire.api.report.TestSetReportEntry;
31 import org.apache.maven.surefire.report.PojoStackTraceWriter;
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.junit.jupiter.api.DisplayName;
35 import org.junit.jupiter.api.DisplayNameGenerator;
36 import org.junit.jupiter.engine.config.DefaultJupiterConfiguration;
37 import org.junit.jupiter.engine.config.JupiterConfiguration;
38 import org.junit.jupiter.engine.descriptor.ClassTestDescriptor;
39 import org.junit.jupiter.engine.descriptor.TestMethodTestDescriptor;
40 import org.junit.jupiter.engine.descriptor.TestTemplateTestDescriptor;
41 import org.junit.platform.engine.ConfigurationParameters;
42 import org.junit.platform.engine.TestDescriptor;
43 import org.junit.platform.engine.TestSource;
44 import org.junit.platform.engine.UniqueId;
45 import org.junit.platform.engine.support.descriptor.AbstractTestDescriptor;
46 import org.junit.platform.engine.support.descriptor.ClassSource;
47 import org.junit.platform.engine.support.descriptor.EngineDescriptor;
48 import org.junit.platform.engine.support.descriptor.MethodSource;
49 import org.junit.platform.launcher.TestIdentifier;
50 import org.junit.platform.launcher.TestPlan;
51 import org.mockito.ArgumentCaptor;
52 import org.mockito.InOrder;
53 import org.opentest4j.TestSkippedException;
54
55 import static java.util.Collections.emptyList;
56 import static java.util.Collections.singleton;
57 import static java.util.Collections.singletonList;
58 import static org.apache.maven.surefire.api.report.RunMode.NORMAL_RUN;
59 import static org.assertj.core.api.Assertions.assertThat;
60 import static org.junit.jupiter.api.Assertions.assertEquals;
61 import static org.junit.jupiter.api.Assertions.assertNotNull;
62 import static org.junit.jupiter.api.Assertions.assertNull;
63 import static org.junit.platform.engine.TestDescriptor.Type.CONTAINER;
64 import static org.junit.platform.engine.TestDescriptor.Type.TEST;
65 import static org.junit.platform.engine.TestExecutionResult.aborted;
66 import static org.junit.platform.engine.TestExecutionResult.failed;
67 import static org.junit.platform.engine.TestExecutionResult.successful;
68 import static org.mockito.ArgumentMatchers.any;
69 import static org.mockito.Mockito.inOrder;
70 import static org.mockito.Mockito.mock;
71 import static org.mockito.Mockito.never;
72 import static org.mockito.Mockito.verify;
73 import static org.mockito.Mockito.verifyNoMoreInteractions;
74 import static org.mockito.Mockito.verifyZeroInteractions;
75 import static org.mockito.Mockito.when;
76 import static org.powermock.reflect.Whitebox.getInternalState;
77
78
79
80
81
82
83 @SuppressWarnings("checkstyle:magicnumber")
84 public class RunListenerAdapterTest {
85 private static final ConfigurationParameters CONFIG_PARAMS = mock(ConfigurationParameters.class);
86
87 private TestReportListener<TestOutputReportEntry> listener;
88
89 private RunListenerAdapter adapter;
90
91 @Before
92 public void setUp() {
93 listener = mock(TestReportListener.class);
94 adapter = new RunListenerAdapter(listener);
95 adapter.testPlanExecutionStarted(TestPlan.from(emptyList(), CONFIG_PARAMS));
96 adapter.setRunMode(NORMAL_RUN);
97 }
98
99 @Test
100 public void notifiedWithCorrectNamesWhenMethodExecutionStarted() throws Exception {
101 ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass(ReportEntry.class);
102
103 TestPlan testPlan = TestPlan.from(singletonList(new EngineDescriptor(newId(), "Luke's Plan")), CONFIG_PARAMS);
104 adapter.testPlanExecutionStarted(testPlan);
105
106 TestIdentifier methodIdentifier =
107 identifiersAsParentOnTestPlan(testPlan, newClassDescriptor(), newMethodDescriptor());
108
109 adapter.executionStarted(methodIdentifier);
110 verify(listener).testStarting(entryCaptor.capture());
111
112 ReportEntry entry = entryCaptor.getValue();
113 assertEquals(MY_TEST_METHOD_NAME, entry.getName());
114 assertEquals(MyTestClass.class.getName(), entry.getSourceName());
115 assertNull(entry.getStackTraceWriter());
116 }
117
118 @Test
119 public void notifiedWithCompatibleNameForMethodWithArguments() throws Exception {
120 ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass(ReportEntry.class);
121
122 TestPlan testPlan = TestPlan.from(singletonList(new EngineDescriptor(newId(), "Luke's Plan")), CONFIG_PARAMS);
123 adapter.testPlanExecutionStarted(testPlan);
124
125 TestIdentifier methodIdentifier =
126 identifiersAsParentOnTestPlan(testPlan, newClassDescriptor(), newMethodDescriptor(String.class));
127
128 adapter.executionStarted(methodIdentifier);
129 verify(listener).testStarting(entryCaptor.capture());
130
131 ReportEntry entry = entryCaptor.getValue();
132 assertEquals(MY_TEST_METHOD_NAME + "(String)", entry.getName());
133 assertNull(entry.getNameText());
134 assertEquals(MyTestClass.class.getName(), entry.getSourceName());
135 assertNull(entry.getSourceText());
136 assertNull(entry.getStackTraceWriter());
137 }
138
139 @Test
140 public void notifiedEagerlyForTestSetWhenClassExecutionStarted() throws Exception {
141 EngineDescriptor engine = newEngineDescriptor();
142 TestDescriptor parent = newClassDescriptor();
143 engine.addChild(parent);
144 TestDescriptor child = newMethodDescriptor();
145 parent.addChild(child);
146 TestPlan plan = TestPlan.from(singletonList(engine), CONFIG_PARAMS);
147
148 String className = MyTestClass.class.getName();
149
150 adapter.testPlanExecutionStarted(plan);
151 adapter.executionStarted(TestIdentifier.from(engine));
152 adapter.executionStarted(TestIdentifier.from(parent));
153 verify(listener)
154 .testSetStarting(new SimpleReportEntry(NORMAL_RUN, 0x0000000100000000L, className, null, null, null));
155 verifyNoMoreInteractions(listener);
156
157 adapter.executionStarted(TestIdentifier.from(child));
158 verify(listener)
159 .testStarting(new SimpleReportEntry(
160 NORMAL_RUN, 0x0000000100000001L, className, null, MY_TEST_METHOD_NAME, null));
161 verifyNoMoreInteractions(listener);
162
163 adapter.executionFinished(TestIdentifier.from(child), successful());
164 ArgumentCaptor<SimpleReportEntry> report = ArgumentCaptor.forClass(SimpleReportEntry.class);
165 verify(listener).testSucceeded(report.capture());
166 assertThat(report.getValue().getRunMode()).isEqualTo(NORMAL_RUN);
167 assertThat(report.getValue().getTestRunId()).isEqualTo(0x0000000100000001L);
168 assertThat(report.getValue().getSourceName()).isEqualTo(className);
169 assertThat(report.getValue().getSourceText()).isNull();
170 assertThat(report.getValue().getName()).isEqualTo(MY_TEST_METHOD_NAME);
171 assertThat(report.getValue().getNameText()).isNull();
172 assertThat(report.getValue().getElapsed()).isNotNull();
173 assertThat(report.getValue().getSystemProperties()).isEmpty();
174 verifyNoMoreInteractions(listener);
175
176 adapter.executionFinished(TestIdentifier.from(parent), successful());
177 report = ArgumentCaptor.forClass(SimpleReportEntry.class);
178 verify(listener).testSetCompleted(report.capture());
179 assertThat(report.getValue().getSourceName()).isEqualTo(className);
180 assertThat(report.getValue().getName()).isNull();
181 assertThat(report.getValue().getElapsed()).isNotNull();
182 assertThat(report.getValue().getSystemProperties()).isNotEmpty();
183 verifyNoMoreInteractions(listener);
184
185 adapter.executionFinished(TestIdentifier.from(engine), successful());
186 verifyNoMoreInteractions(listener);
187 }
188
189 @Test
190 public void displayNamesInClassAndMethods() throws Exception {
191 EngineDescriptor engine = newEngineDescriptor();
192 TestDescriptor parent = newClassDescriptor("parent");
193 engine.addChild(parent);
194
195 UniqueId id1 = parent.getUniqueId().append(MyTestClass.class.getName(), MY_NAMED_TEST_METHOD_NAME);
196 Method m1 = MyTestClass.class.getDeclaredMethod(MY_NAMED_TEST_METHOD_NAME);
197 TestDescriptor child1 = new TestMethodTestDescriptorWithDisplayName(id1, MyTestClass.class, m1, "dn1");
198 parent.addChild(child1);
199
200 UniqueId id2 = parent.getUniqueId().append(MyTestClass.class.getName(), MY_TEST_METHOD_NAME);
201 Method m2 = MyTestClass.class.getDeclaredMethod(MY_TEST_METHOD_NAME, String.class);
202 TestDescriptor child2 = new TestMethodTestDescriptor(
203 id2, MyTestClass.class, m2, new DefaultJupiterConfiguration(CONFIG_PARAMS));
204 parent.addChild(child2);
205
206 TestPlan plan = TestPlan.from(singletonList(engine), CONFIG_PARAMS);
207
208 InOrder inOrder = inOrder(listener);
209
210 adapter.testPlanExecutionStarted(plan);
211
212 adapter.executionStarted(TestIdentifier.from(engine));
213 adapter.executionStarted(TestIdentifier.from(parent));
214 ArgumentCaptor<SimpleReportEntry> report = ArgumentCaptor.forClass(SimpleReportEntry.class);
215 inOrder.verify(listener).testSetStarting(report.capture());
216 assertThat(report.getValue().getTestRunId()).isEqualTo(0x0000000100000000L);
217 assertThat(report.getValue().getSourceName()).isEqualTo(MyTestClass.class.getName());
218 assertThat(report.getValue().getSourceText()).isEqualTo("parent");
219 assertThat(report.getValue().getName()).isNull();
220 assertThat(report.getValue().getSystemProperties()).isEmpty();
221 verifyZeroInteractions(listener);
222
223 adapter.executionStarted(TestIdentifier.from(child1));
224 inOrder.verify(listener)
225 .testStarting(new SimpleReportEntry(
226 NORMAL_RUN,
227 0x0000000100000001L,
228 MyTestClass.class.getName(),
229 "parent",
230 MY_NAMED_TEST_METHOD_NAME,
231 "dn1"));
232 inOrder.verifyNoMoreInteractions();
233
234 adapter.executionFinished(TestIdentifier.from(child1), successful());
235 report = ArgumentCaptor.forClass(SimpleReportEntry.class);
236 inOrder.verify(listener).testSucceeded(report.capture());
237 assertThat(report.getValue().getRunMode()).isEqualTo(NORMAL_RUN);
238 assertThat(report.getValue().getTestRunId()).isEqualTo(0x0000000100000001L);
239 assertThat(report.getValue().getSourceName()).isEqualTo(MyTestClass.class.getName());
240 assertThat(report.getValue().getSourceText()).isEqualTo("parent");
241 assertThat(report.getValue().getName()).isEqualTo(MY_NAMED_TEST_METHOD_NAME);
242 assertThat(report.getValue().getNameText()).isEqualTo("dn1");
243 assertThat(report.getValue().getElapsed()).isNotNull();
244 assertThat(report.getValue().getSystemProperties()).isEmpty();
245 inOrder.verifyNoMoreInteractions();
246
247 adapter.executionStarted(TestIdentifier.from(child2));
248 inOrder.verify(listener)
249 .testStarting(new SimpleReportEntry(
250 NORMAL_RUN,
251 0x0000000100000002L,
252 MyTestClass.class.getName(),
253 "parent",
254 MY_TEST_METHOD_NAME + "(String)",
255 null));
256 inOrder.verifyNoMoreInteractions();
257
258 Exception assumptionFailure = new Exception();
259 adapter.executionFinished(TestIdentifier.from(child2), aborted(assumptionFailure));
260 report = ArgumentCaptor.forClass(SimpleReportEntry.class);
261 inOrder.verify(listener).testAssumptionFailure(report.capture());
262 assertThat(report.getValue().getRunMode()).isEqualTo(NORMAL_RUN);
263 assertThat(report.getValue().getTestRunId()).isEqualTo(0x0000000100000002L);
264 assertThat(report.getValue().getSourceName()).isEqualTo(MyTestClass.class.getName());
265 assertThat(report.getValue().getSourceText()).isEqualTo("parent");
266 assertThat(report.getValue().getName()).isEqualTo(MY_TEST_METHOD_NAME + "(String)");
267 assertThat(report.getValue().getNameText()).isNull();
268 assertThat(report.getValue().getElapsed()).isNotNull();
269 assertThat(report.getValue().getSystemProperties()).isEmpty();
270 assertThat(report.getValue().getStackTraceWriter()).isNotNull();
271 assertThat(report.getValue().getStackTraceWriter().getThrowable().getTarget())
272 .isSameAs(assumptionFailure);
273 inOrder.verifyNoMoreInteractions();
274
275 adapter.executionFinished(TestIdentifier.from(parent), successful());
276 inOrder.verify(listener).testSetCompleted(report.capture());
277 assertThat(report.getValue().getSourceName()).isEqualTo(MyTestClass.class.getName());
278 assertThat(report.getValue().getSourceText()).isEqualTo("parent");
279 assertThat(report.getValue().getName()).isNull();
280 assertThat(report.getValue().getNameText()).isNull();
281 assertThat(report.getValue().getElapsed()).isNotNull();
282 assertThat(report.getValue().getSystemProperties()).isNotEmpty();
283 assertThat(report.getValue().getStackTraceWriter()).isNull();
284 inOrder.verifyNoMoreInteractions();
285
286 adapter.executionFinished(TestIdentifier.from(engine), successful());
287 inOrder.verifyNoMoreInteractions();
288 }
289
290 @Test
291 public void notifiedForUnclassifiedTestIdentifier() {
292 EngineDescriptor engine = new EngineDescriptor(UniqueId.forEngine("engine"), "engine") {
293 @Override
294 public Type getType() {
295 return TEST;
296 }
297 };
298 TestPlan plan = TestPlan.from(singletonList(engine), CONFIG_PARAMS);
299
300 adapter.testPlanExecutionStarted(plan);
301 assertThat((TestPlan) getInternalState(adapter, "testPlan")).isSameAs(plan);
302 assertThat((Map) getInternalState(adapter, "testStartTime")).isEmpty();
303
304 adapter.executionStarted(TestIdentifier.from(engine));
305 verify(listener)
306 .testStarting(new SimpleReportEntry(NORMAL_RUN, 0x0000000100000001L, "engine", null, "engine", null));
307 verifyNoMoreInteractions(listener);
308
309 adapter.executionFinished(TestIdentifier.from(engine), successful());
310 ArgumentCaptor<SimpleReportEntry> report = ArgumentCaptor.forClass(SimpleReportEntry.class);
311 verify(listener).testSucceeded(report.capture());
312 assertThat(report.getValue().getRunMode()).isEqualTo(NORMAL_RUN);
313 assertThat(report.getValue().getTestRunId()).isEqualTo(0x0000000100000001L);
314 assertThat(report.getValue().getSourceName()).isEqualTo("engine");
315 assertThat(report.getValue().getSourceText()).isNull();
316 assertThat(report.getValue().getName()).isEqualTo("engine");
317 assertThat(report.getValue().getNameText()).isNull();
318 assertThat(report.getValue().getElapsed()).isNotNull();
319 assertThat(report.getValue().getStackTraceWriter()).isNull();
320 assertThat(report.getValue().getSystemProperties()).isEmpty();
321
322 adapter.testPlanExecutionFinished(plan);
323 assertThat((TestPlan) getInternalState(adapter, "testPlan")).isNull();
324 assertThat((Map) getInternalState(adapter, "testStartTime")).isEmpty();
325
326 verifyNoMoreInteractions(listener);
327 }
328
329 @Test
330 public void notNotifiedWhenEngineExecutionStarted() {
331 adapter.executionStarted(newEngineIdentifier());
332 verify(listener, never()).testStarting(any());
333 }
334
335 @Test
336 public void notifiedWhenMethodExecutionSkipped() throws Exception {
337 adapter.executionSkipped(newMethodIdentifier(), "test");
338 verify(listener).testSkipped(any());
339 }
340
341 @Test
342 public void notifiedWithCorrectNamesWhenClassExecutionSkipped() throws Exception {
343 EngineDescriptor engineDescriptor = new EngineDescriptor(newId(), "Luke's Plan");
344 TestDescriptor classTestDescriptor = newClassDescriptor();
345 TestDescriptor method1 = newMethodDescriptor();
346 classTestDescriptor.addChild(method1);
347 TestDescriptor method2 = newMethodDescriptor();
348 classTestDescriptor.addChild(method2);
349 engineDescriptor.addChild(classTestDescriptor);
350 TestPlan testPlan = TestPlan.from(singletonList(engineDescriptor), CONFIG_PARAMS);
351 adapter.testPlanExecutionStarted(testPlan);
352
353 TestIdentifier classIdentifier =
354 identifiersAsParentOnTestPlan(testPlan, newEngineDescriptor(), newClassDescriptor());
355
356 ArgumentCaptor<TestSetReportEntry> entryCaptor1 = ArgumentCaptor.forClass(TestSetReportEntry.class);
357 ArgumentCaptor<ReportEntry> entryCaptor2 = ArgumentCaptor.forClass(ReportEntry.class);
358 ArgumentCaptor<ReportEntry> entryCaptor3 = ArgumentCaptor.forClass(ReportEntry.class);
359 ArgumentCaptor<TestSetReportEntry> entryCaptor4 = ArgumentCaptor.forClass(TestSetReportEntry.class);
360
361 adapter.executionSkipped(classIdentifier, "test");
362 verify(listener).testSetStarting(entryCaptor1.capture());
363 verify(listener).testSkipped(entryCaptor2.capture());
364 verify(listener).testSkipped(entryCaptor3.capture());
365 verify(listener).testSetCompleted(entryCaptor4.capture());
366
367 ReportEntry entry1 = entryCaptor1.getValue();
368 assertNull(entry1.getName());
369 assertEquals(MyTestClass.class.getTypeName(), entry1.getSourceName());
370
371 ReportEntry entry4 = entryCaptor1.getValue();
372 assertNull(entry4.getName());
373 assertEquals(MyTestClass.class.getTypeName(), entry4.getSourceName());
374 }
375
376 @Test
377 public void notifiedWhenMethodExecutionAborted() throws Exception {
378 adapter.executionFinished(newMethodIdentifier(), aborted(null));
379 verify(listener).testAssumptionFailure(any());
380 }
381
382 @Test
383 public void notifiedWhenClassExecutionAborted() {
384 TestSkippedException t = new TestSkippedException("skipped");
385 adapter.executionFinished(newClassIdentifier(), aborted(t));
386 String source = MyTestClass.class.getName();
387 StackTraceWriter stw = new PojoStackTraceWriter(source, null, t);
388 ArgumentCaptor<SimpleReportEntry> report = ArgumentCaptor.forClass(SimpleReportEntry.class);
389 verify(listener).testSetCompleted(report.capture());
390 assertThat(report.getValue().getSourceName()).isEqualTo(source);
391 assertThat(report.getValue().getStackTraceWriter()).isEqualTo(stw);
392 }
393
394 @Test
395 public void notifiedOfContainerFailureWhenErrored() throws Exception {
396 adapter.executionFinished(newContainerIdentifier(), failed(new RuntimeException()));
397 verify(listener).testError(any());
398 }
399
400 @Test
401 public void notifiedOfContainerFailureWhenFailed() throws Exception {
402 adapter.executionFinished(newContainerIdentifier(), failed(new AssertionError()));
403 verify(listener).testFailed(any());
404 }
405
406 @Test
407 public void notifiedWhenMethodExecutionFailed() throws Exception {
408 adapter.executionFinished(newMethodIdentifier(), failed(new AssertionError()));
409 verify(listener).testFailed(any());
410 }
411
412 @Test
413 public void notifiedWhenMethodExecutionFailedWithError() throws Exception {
414 adapter.executionFinished(newMethodIdentifier(), failed(new RuntimeException()));
415 verify(listener).testError(any());
416 }
417
418 @Test
419 public void notifiedWithCorrectNamesWhenClassExecutionFailed() {
420 ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass(ReportEntry.class);
421 TestPlan testPlan = TestPlan.from(singletonList(new EngineDescriptor(newId(), "Luke's Plan")), CONFIG_PARAMS);
422 adapter.testPlanExecutionStarted(testPlan);
423
424 adapter.executionFinished(
425 identifiersAsParentOnTestPlan(testPlan, newClassDescriptor()), failed(new AssertionError()));
426 verify(listener).testFailed(entryCaptor.capture());
427
428 ReportEntry entry = entryCaptor.getValue();
429 assertEquals(MyTestClass.class.getTypeName(), entry.getSourceName());
430 assertNull(entry.getName());
431 assertNotNull(entry.getStackTraceWriter());
432 assertNotNull(entry.getStackTraceWriter().getThrowable());
433 assertThat(entry.getStackTraceWriter().getThrowable().getTarget()).isInstanceOf(AssertionError.class);
434 }
435
436 @Test
437 public void notifiedWithCorrectNamesWhenClassExecutionErrored() {
438 ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass(ReportEntry.class);
439 TestPlan testPlan = TestPlan.from(singletonList(new EngineDescriptor(newId(), "Luke's Plan")), CONFIG_PARAMS);
440 adapter.testPlanExecutionStarted(testPlan);
441
442 adapter.executionFinished(
443 identifiersAsParentOnTestPlan(testPlan, newClassDescriptor()), failed(new RuntimeException()));
444 verify(listener).testError(entryCaptor.capture());
445
446 ReportEntry entry = entryCaptor.getValue();
447 assertEquals(MyTestClass.class.getTypeName(), entry.getSourceName());
448 assertNull(entry.getName());
449 assertNotNull(entry.getStackTraceWriter());
450 assertNotNull(entry.getStackTraceWriter().getThrowable());
451 assertThat(entry.getStackTraceWriter().getThrowable().getTarget()).isInstanceOf(RuntimeException.class);
452 }
453
454 @Test
455 public void notifiedWithCorrectNamesWhenContainerFailed() throws Exception {
456 ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass(ReportEntry.class);
457 TestPlan testPlan = TestPlan.from(singletonList(new EngineDescriptor(newId(), "Luke's Plan")), CONFIG_PARAMS);
458 adapter.testPlanExecutionStarted(testPlan);
459
460 adapter.executionFinished(newContainerIdentifier(), failed(new RuntimeException()));
461 verify(listener).testError(entryCaptor.capture());
462
463 ReportEntry entry = entryCaptor.getValue();
464 assertEquals(MyTestClass.class.getTypeName(), entry.getSourceName());
465 assertEquals(MY_TEST_METHOD_NAME, entry.getName());
466 assertNotNull(entry.getStackTraceWriter());
467 assertNotNull(entry.getStackTraceWriter().getThrowable());
468 assertThat(entry.getStackTraceWriter().getThrowable().getTarget()).isInstanceOf(RuntimeException.class);
469 }
470
471 @Test
472 public void notifiedWhenMethodExecutionSucceeded() throws Exception {
473 adapter.executionFinished(newMethodIdentifier(), successful());
474 verify(listener).testSucceeded(any());
475 }
476
477 @Test
478 public void notifiedForTestSetWhenClassExecutionSucceeded() {
479 EngineDescriptor engineDescriptor = newEngineDescriptor();
480 TestDescriptor classDescriptor = newClassDescriptor();
481 engineDescriptor.addChild(classDescriptor);
482 adapter.testPlanExecutionStarted(TestPlan.from(singleton(engineDescriptor), CONFIG_PARAMS));
483 adapter.executionStarted(TestIdentifier.from(classDescriptor));
484
485 adapter.executionFinished(TestIdentifier.from(classDescriptor), successful());
486
487 String className = MyTestClass.class.getName();
488
489 verify(listener)
490 .testSetStarting(new SimpleReportEntry(NORMAL_RUN, 0x0000000100000000L, className, null, null, null));
491
492 ArgumentCaptor<SimpleReportEntry> report = ArgumentCaptor.forClass(SimpleReportEntry.class);
493 verify(listener).testSetCompleted(report.capture());
494 assertThat(report.getValue().getRunMode()).isEqualTo(NORMAL_RUN);
495 assertThat(report.getValue().getTestRunId()).isEqualTo(0x0000000100000000L);
496 assertThat(report.getValue().getSourceName()).isEqualTo(className);
497 assertThat(report.getValue().getSourceText()).isNull();
498 assertThat(report.getValue().getName()).isNull();
499 assertThat(report.getValue().getNameText()).isNull();
500 assertThat(report.getValue().getStackTraceWriter()).isNull();
501 assertThat(report.getValue().getElapsed()).isNotNull();
502 assertThat(report.getValue().getSystemProperties()).isNotEmpty();
503
504 verify(listener, never()).testSucceeded(any());
505
506 verifyNoMoreInteractions(listener);
507 }
508
509 @Test
510 public void notifiedWithParentDisplayNameWhenTestClassUnknown() {
511
512 TestPlan plan = TestPlan.from(singletonList(new EngineDescriptor(newId(), "Luke's Plan")), CONFIG_PARAMS);
513 adapter.testPlanExecutionStarted(plan);
514
515
516 final String parentDisplay = "I am your father";
517 TestIdentifier child = newSourcelessChildIdentifierWithParent(plan, parentDisplay, null);
518 adapter.executionStarted(child);
519
520
521
522 ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass(ReportEntry.class);
523 verify(listener).testStarting(entryCaptor.capture());
524 assertEquals(parentDisplay, entryCaptor.getValue().getSourceName());
525 assertNull(entryCaptor.getValue().getSourceText());
526 assertNull(entryCaptor.getValue().getName());
527 assertNull(entryCaptor.getValue().getNameText());
528 }
529
530 @Test
531 public void stackTraceWriterPresentWhenParentHasSource() {
532 TestPlan plan = TestPlan.from(singletonList(new EngineDescriptor(newId(), "Some Plan")), CONFIG_PARAMS);
533 adapter.testPlanExecutionStarted(plan);
534
535 TestIdentifier child =
536 newSourcelessChildIdentifierWithParent(plan, "Parent", ClassSource.from(MyTestClass.class));
537 adapter.executionFinished(child, failed(new RuntimeException()));
538 ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass(ReportEntry.class);
539 verify(listener).testError(entryCaptor.capture());
540 assertNotNull(entryCaptor.getValue().getStackTraceWriter());
541 }
542
543 @Test
544 public void stackTraceWriterDefaultsToTestClass() {
545 TestPlan plan = TestPlan.from(singletonList(new EngineDescriptor(newId(), "Some Plan")), CONFIG_PARAMS);
546 adapter.testPlanExecutionStarted(plan);
547
548 TestIdentifier child = newSourcelessChildIdentifierWithParent(plan, "Parent", null);
549 adapter.executionFinished(child, failed(new RuntimeException("message")));
550 ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass(ReportEntry.class);
551 verify(listener).testError(entryCaptor.capture());
552 assertNotNull(entryCaptor.getValue().getStackTraceWriter());
553 assertNotNull(entryCaptor.getValue().getStackTraceWriter().smartTrimmedStackTrace());
554 assertNotNull(entryCaptor.getValue().getStackTraceWriter().writeTraceToString());
555 assertNotNull(entryCaptor.getValue().getStackTraceWriter().writeTrimmedTraceToString());
556 }
557
558 @Test
559 public void stackTraceWriterPresentEvenWithoutException() throws Exception {
560 adapter.executionFinished(newMethodIdentifier(), failed(null));
561 ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass(ReportEntry.class);
562 verify(listener).testError(entryCaptor.capture());
563 assertNotNull(entryCaptor.getValue().getStackTraceWriter());
564 }
565
566 @Test
567 public void displayNamesIgnoredInReport() throws NoSuchMethodException {
568 TestMethodTestDescriptorWithDisplayName descriptor = new TestMethodTestDescriptorWithDisplayName(
569 newId(),
570 MyTestClass.class,
571 MyTestClass.class.getDeclaredMethod("myNamedTestMethod"),
572 "some display name");
573
574 TestIdentifier factoryIdentifier = TestIdentifier.from(descriptor);
575 ArgumentCaptor<ReportEntry> entryCaptor = ArgumentCaptor.forClass(ReportEntry.class);
576
577 adapter.executionSkipped(factoryIdentifier, "");
578 verify(listener).testSkipped(entryCaptor.capture());
579
580 ReportEntry value = entryCaptor.getValue();
581
582 assertEquals(MyTestClass.class.getName(), value.getSourceName());
583 assertNull(value.getSourceText());
584 assertEquals("myNamedTestMethod", value.getName());
585 assertEquals("some display name", value.getNameText());
586 }
587
588 private static TestIdentifier newMethodIdentifier() throws Exception {
589 return TestIdentifier.from(newMethodDescriptor());
590 }
591
592 private static TestDescriptor newMethodDescriptor(Class<?>... parameterTypes) throws Exception {
593 return new TestMethodTestDescriptor(
594 UniqueId.forEngine("method"),
595 MyTestClass.class,
596 MyTestClass.class.getDeclaredMethod(MY_TEST_METHOD_NAME, parameterTypes),
597 new DefaultJupiterConfiguration(CONFIG_PARAMS));
598 }
599
600 private static TestIdentifier newClassIdentifier() {
601 return TestIdentifier.from(newClassDescriptor());
602 }
603
604 private static TestDescriptor newClassDescriptor(String displayName) {
605 JupiterConfiguration jupiterConfiguration = mock(JupiterConfiguration.class);
606 DisplayNameGenerator displayNameGenerator = mock(DisplayNameGenerator.class);
607 when(displayNameGenerator.generateDisplayNameForClass(MyTestClass.class))
608 .thenReturn(displayName);
609 when(jupiterConfiguration.getDefaultDisplayNameGenerator()).thenReturn(displayNameGenerator);
610 return new ClassTestDescriptor(
611 UniqueId.root("class", MyTestClass.class.getName()), MyTestClass.class, jupiterConfiguration) {};
612 }
613
614 private static TestDescriptor newClassDescriptor() {
615 return new ClassTestDescriptor(
616 UniqueId.root("class", MyTestClass.class.getName()),
617 MyTestClass.class,
618 new DefaultJupiterConfiguration(CONFIG_PARAMS));
619 }
620
621 private static TestIdentifier newSourcelessChildIdentifierWithParent(
622 TestPlan testPlan, String parentDisplay, TestSource parentTestSource) {
623
624 TestDescriptor parent = mock(TestDescriptor.class);
625 when(parent.getUniqueId()).thenReturn(newId());
626 when(parent.getDisplayName()).thenReturn(parentDisplay);
627 when(parent.getLegacyReportingName()).thenReturn(parentDisplay);
628 when(parent.getSource()).thenReturn(Optional.ofNullable(parentTestSource));
629 when(parent.getType()).thenReturn(CONTAINER);
630 TestIdentifier parentId = TestIdentifier.from(parent);
631
632
633 TestDescriptor child = mock(TestDescriptor.class);
634 when(child.getUniqueId()).thenReturn(newId());
635 when(child.getType()).thenReturn(TEST);
636 when(child.getLegacyReportingName()).thenReturn("child");
637
638
639 when(child.getSource()).thenReturn(Optional.empty());
640 when(child.getParent()).thenReturn(Optional.of(parent));
641 TestIdentifier childId = TestIdentifier.from(child);
642
643 testPlan.addInternal(childId);
644 testPlan.addInternal(parentId);
645
646 return childId;
647 }
648
649 private static TestIdentifier newContainerIdentifier() throws Exception {
650 return TestIdentifier.from(new TestTemplateTestDescriptor(
651 UniqueId.forEngine("method"),
652 MyTestClass.class,
653 MyTestClass.class.getDeclaredMethod(MY_TEST_METHOD_NAME),
654 new DefaultJupiterConfiguration(CONFIG_PARAMS)));
655 }
656
657 private static TestIdentifier newEngineIdentifier() {
658 TestDescriptor testDescriptor = newEngineDescriptor();
659 return TestIdentifier.from(testDescriptor);
660 }
661
662 private static EngineDescriptor newEngineDescriptor() {
663 return new EngineDescriptor(UniqueId.forEngine("engine"), "engine");
664 }
665
666 private static TestIdentifier identifiersAsParentOnTestPlan(
667 TestPlan plan, TestDescriptor parent, TestDescriptor child) {
668 child.setParent(parent);
669
670 TestIdentifier parentIdentifier = TestIdentifier.from(parent);
671 TestIdentifier childIdentifier = TestIdentifier.from(child);
672
673 plan.addInternal(parentIdentifier);
674 plan.addInternal(childIdentifier);
675
676 return childIdentifier;
677 }
678
679 private static TestIdentifier identifiersAsParentOnTestPlan(TestPlan plan, TestDescriptor root) {
680 TestIdentifier rootIdentifier = TestIdentifier.from(root);
681 plan.addInternal(rootIdentifier);
682 return rootIdentifier;
683 }
684
685 private static UniqueId newId() {
686 return UniqueId.forEngine("engine");
687 }
688
689 private static final String MY_TEST_METHOD_NAME = "myTestMethod";
690 private static final String MY_NAMED_TEST_METHOD_NAME = "myNamedTestMethod";
691
692 private static class MyTestClass {
693 @org.junit.jupiter.api.Test
694 void myTestMethod() {}
695
696 @org.junit.jupiter.api.Test
697 void myTestMethod(String foo) {}
698
699 @DisplayName("name")
700 @org.junit.jupiter.api.Test
701 void myNamedTestMethod() {}
702 }
703
704 static class TestMethodTestDescriptorWithDisplayName extends AbstractTestDescriptor {
705 private TestMethodTestDescriptorWithDisplayName(
706 UniqueId uniqueId, Class<?> testClass, Method testMethod, String displayName) {
707 super(uniqueId, displayName, MethodSource.from(testClass, testMethod));
708 }
709
710 @Override
711 public Type getType() {
712 return Type.TEST;
713 }
714 }
715 }