Skip to content

Commit f9c509d

Browse files
committed
Synthesize start/finished events for reported failures
When Spock data-provider preparation fails early, it only calls `RunListener.testFailure` but not `testFinished` which caused the Vintage engine to never report the failure. Now, when `testFailure` is called a `testStarted` event is synthesized unless it was already reported. The existing handling of synthetic start events then reports it as finished. Fixes #1845.
1 parent e3d13cf commit f9c509d

File tree

5 files changed

+118
-7
lines changed

5 files changed

+118
-7
lines changed

junit-vintage-engine/src/main/java/org/junit/vintage/engine/execution/RunListenerAdapter.java

+2-7
Original file line numberDiff line numberDiff line change
@@ -124,16 +124,11 @@ private void handleFailure(Failure failure, Function<Throwable, TestExecutionRes
124124
TestDescriptor testDescriptor) {
125125
TestExecutionResult result = resultCreator.apply(failure.getException());
126126
testRun.storeResult(testDescriptor, result);
127-
if (testDescriptor.isContainer() && testRun.isDescendantOfRunnerTestDescriptor(testDescriptor)) {
128-
fireMissingContainerEvents(testDescriptor);
129-
}
130-
}
131-
132-
private void fireMissingContainerEvents(TestDescriptor testDescriptor) {
133127
if (testRun.isNotStarted(testDescriptor)) {
134128
testStarted(testDescriptor, EventType.SYNTHETIC);
135129
}
136-
if (testRun.isNotFinished(testDescriptor)) {
130+
if (testRun.isNotFinished(testDescriptor) && testDescriptor.isContainer()
131+
&& testRun.isDescendantOfRunnerTestDescriptor(testDescriptor)) {
137132
testFinished(testDescriptor);
138133
}
139134
}

junit-vintage-engine/src/test/java/org/junit/vintage/engine/VintageTestEngineExecutionTests.java

+36
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,14 @@
6161
import org.junit.vintage.engine.samples.junit4.JUnit4SuiteWithJUnit3SuiteWithSingleTestCase;
6262
import org.junit.vintage.engine.samples.junit4.JUnit4SuiteWithJUnit4TestCaseWithAssumptionFailureInBeforeClass;
6363
import org.junit.vintage.engine.samples.junit4.JUnit4SuiteWithJUnit4TestCaseWithErrorInBeforeClass;
64+
import org.junit.vintage.engine.samples.junit4.JUnit4SuiteWithJUnit4TestCaseWithFailingDescriptionThatIsNotReportedAsFinished;
6465
import org.junit.vintage.engine.samples.junit4.JUnit4SuiteWithPlainJUnit4TestCaseWithSingleTestWhichIsIgnored;
6566
import org.junit.vintage.engine.samples.junit4.JUnit4TestCaseWithAssumptionFailureInBeforeClass;
6667
import org.junit.vintage.engine.samples.junit4.JUnit4TestCaseWithErrorCollectorStoringMultipleFailures;
6768
import org.junit.vintage.engine.samples.junit4.JUnit4TestCaseWithErrorInAfterClass;
6869
import org.junit.vintage.engine.samples.junit4.JUnit4TestCaseWithErrorInBeforeClass;
6970
import org.junit.vintage.engine.samples.junit4.JUnit4TestCaseWithExceptionThrowingRunner;
71+
import org.junit.vintage.engine.samples.junit4.JUnit4TestCaseWithFailingDescriptionThatIsNotReportedAsFinished;
7072
import org.junit.vintage.engine.samples.junit4.JUnit4TestCaseWithOverloadedMethod;
7173
import org.junit.vintage.engine.samples.junit4.JUnit4TestCaseWithRunnerWithCustomUniqueIds;
7274
import org.junit.vintage.engine.samples.junit4.MalformedJUnit4TestCase;
@@ -624,6 +626,40 @@ void executesJUnit4TestCaseWithErrorCollectorStoringMultipleFailures() {
624626
event(engine(), finishedSuccessfully()));
625627
}
626628

629+
@Test
630+
void executesJUnit4TestCaseWithFailingDescriptionThatIsNotReportedAsFinished() {
631+
Class<?> testClass = JUnit4TestCaseWithFailingDescriptionThatIsNotReportedAsFinished.class;
632+
633+
execute(testClass).assertEventsMatchExactly( //
634+
event(engine(), started()), //
635+
event(container(testClass), started()), //
636+
event(test("testWithMissingEvents"), started()), //
637+
event(test("testWithMissingEvents"), finishedWithFailure()), //
638+
event(container(testClass), finishedSuccessfully()), //
639+
event(engine(), finishedSuccessfully()));
640+
}
641+
642+
@Test
643+
void executesJUnit4SuiteWithJUnit4TestCaseWithFailingDescriptionThatIsNotReportedAsFinished() {
644+
Class<?> suiteClass = JUnit4SuiteWithJUnit4TestCaseWithFailingDescriptionThatIsNotReportedAsFinished.class;
645+
Class<?> firstTestClass = JUnit4TestCaseWithFailingDescriptionThatIsNotReportedAsFinished.class;
646+
Class<?> secondTestClass = PlainJUnit4TestCaseWithSingleTestWhichFails.class;
647+
648+
execute(suiteClass).assertEventsMatchExactly( //
649+
event(engine(), started()), //
650+
event(container(suiteClass), started()), //
651+
event(container(firstTestClass), started()), //
652+
event(test("testWithMissingEvents"), started()), //
653+
event(test("testWithMissingEvents"), finishedWithFailure()), //
654+
event(container(firstTestClass), finishedSuccessfully()), //
655+
event(container(secondTestClass), started()), //
656+
event(test("failingTest"), started()), //
657+
event(test("failingTest"), finishedWithFailure()), //
658+
event(container(secondTestClass), finishedSuccessfully()), //
659+
event(container(suiteClass), finishedSuccessfully()), //
660+
event(engine(), finishedSuccessfully()));
661+
}
662+
627663
private static Events execute(Class<?> testClass) {
628664
return EngineTestKit.execute(new VintageTestEngine(), request(testClass)).all();
629665
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*
2+
* Copyright 2015-2019 the original author or authors.
3+
*
4+
* All rights reserved. This program and the accompanying materials are
5+
* made available under the terms of the Eclipse Public License v2.0 which
6+
* accompanies this distribution and is available at
7+
*
8+
* http://www.eclipse.org/legal/epl-v20.html
9+
*/
10+
11+
package org.junit.vintage.engine.samples.junit4;
12+
13+
import org.junit.runner.RunWith;
14+
import org.junit.runners.Suite;
15+
import org.junit.runners.Suite.SuiteClasses;
16+
17+
@RunWith(Suite.class)
18+
@SuiteClasses({ JUnit4TestCaseWithFailingDescriptionThatIsNotReportedAsFinished.class,
19+
PlainJUnit4TestCaseWithSingleTestWhichFails.class })
20+
public class JUnit4SuiteWithJUnit4TestCaseWithFailingDescriptionThatIsNotReportedAsFinished {
21+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
/*
2+
* Copyright 2015-2019 the original author or authors.
3+
*
4+
* All rights reserved. This program and the accompanying materials are
5+
* made available under the terms of the Eclipse Public License v2.0 which
6+
* accompanies this distribution and is available at
7+
*
8+
* http://www.eclipse.org/legal/epl-v20.html
9+
*/
10+
11+
package org.junit.vintage.engine.samples.junit4;
12+
13+
import static org.junit.Assert.fail;
14+
15+
import org.junit.Test;
16+
import org.junit.runner.RunWith;
17+
18+
@RunWith(RunnerThatOnlyReportsFailures.class)
19+
public class JUnit4TestCaseWithFailingDescriptionThatIsNotReportedAsFinished {
20+
@Test
21+
public void testWithMissingEvents() {
22+
fail("boom");
23+
}
24+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
/*
2+
* Copyright 2015-2019 the original author or authors.
3+
*
4+
* All rights reserved. This program and the accompanying materials are
5+
* made available under the terms of the Eclipse Public License v2.0 which
6+
* accompanies this distribution and is available at
7+
*
8+
* http://www.eclipse.org/legal/epl-v20.html
9+
*/
10+
11+
package org.junit.vintage.engine.samples.junit4;
12+
13+
import org.junit.runner.notification.Failure;
14+
import org.junit.runner.notification.RunNotifier;
15+
import org.junit.runners.BlockJUnit4ClassRunner;
16+
import org.junit.runners.model.FrameworkMethod;
17+
import org.junit.runners.model.InitializationError;
18+
import org.junit.runners.model.Statement;
19+
20+
public class RunnerThatOnlyReportsFailures extends BlockJUnit4ClassRunner {
21+
public RunnerThatOnlyReportsFailures(Class<?> klass) throws InitializationError {
22+
super(klass);
23+
}
24+
25+
@Override
26+
protected void runChild(FrameworkMethod method, RunNotifier notifier) {
27+
Statement statement = methodBlock(method);
28+
try {
29+
statement.evaluate();
30+
}
31+
catch (Throwable e) {
32+
notifier.fireTestFailure(new Failure(describeChild(method), e));
33+
}
34+
}
35+
}

0 commit comments

Comments
 (0)