Skip to content

Commit 51cde87

Browse files
authored
[Core] Emit exceptions on failure to handle test run finished events (#2651)
The runtime would collect exceptions thrown upon emitting the TestRunFinished event. The assumption was that these were collected in the test context. Though this is impossible. The test context is collecting exceptions to include in the report. So it sits inside the test run started and finished events.
1 parent d9a5afd commit 51cde87

File tree

5 files changed

+56
-2
lines changed

5 files changed

+56
-2
lines changed

CHANGELOG.md

+2
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1515
- Enabled reproducible builds ([2641](https://github.com/cucumber/cucumber-jvm/issues/2641) Hervé Boutemy )
1616
- [Core] Mark Allure 5 and 6 plugins as incompatible ([2652](https://github.com/cucumber/cucumber-jvm/issues/2652) M.P. Korstanje)
1717

18+
## Fixed
19+
- [Core] Emit exceptions on failure to handle test run finished events ([2651](https://github.com/cucumber/cucumber-jvm/issues/2651) M.P. Korstanje)
1820

1921
## [7.9.0] - 2022-11-01
2022
### Changed

cucumber-core/src/main/java/io/cucumber/core/runtime/Runtime.java

+5-2
Original file line numberDiff line numberDiff line change
@@ -83,8 +83,11 @@ public void run() {
8383
context.runBeforeAllHooks();
8484
runFeatures(features);
8585
});
86-
execute(context::runAfterAllHooks);
87-
execute(context::finishTestRun);
86+
try {
87+
execute(context::runAfterAllHooks);
88+
} finally {
89+
context.finishTestRun();
90+
}
8891
Throwable exception = context.getThrowable();
8992
if (exception != null) {
9093
throwAsUncheckedException(exception);

cucumber-core/src/test/java/io/cucumber/core/backend/StubPendingException.java

+13
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22

33
import io.cucumber.core.backend.Pending;
44

5+
import java.io.PrintStream;
6+
import java.io.PrintWriter;
7+
58
@Pending
69
public final class StubPendingException extends RuntimeException {
710

@@ -13,4 +16,14 @@ public StubPendingException(String message) {
1316
super(message);
1417
}
1518

19+
@Override
20+
public void printStackTrace(PrintWriter printWriter) {
21+
printWriter.print(getMessage());
22+
}
23+
24+
@Override
25+
public void printStackTrace(PrintStream printStream) {
26+
printStream.print(getMessage());
27+
}
28+
1629
}

cucumber-core/src/test/java/io/cucumber/core/runtime/RuntimeTest.java

+35
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import io.cucumber.plugin.event.TestRunStarted;
3232
import io.cucumber.plugin.event.TestStepFinished;
3333
import io.cucumber.plugin.event.TestStepStarted;
34+
import org.hamcrest.CoreMatchers;
3435
import org.junit.jupiter.api.Test;
3536
import org.junit.jupiter.api.function.Executable;
3637
import org.mockito.ArgumentCaptor;
@@ -366,6 +367,40 @@ void should_fail_on_event_listener_exception_when_running_in_parallel() {
366367
assertThat(actualThrown.getSuppressed(), is(arrayWithSize(3)));
367368
}
368369

370+
@Test
371+
void should_fail_on_event_listener_exception_at_test_run_started() {
372+
RuntimeException expectedException = new RuntimeException("This exception is expected");
373+
ConcurrentEventListener brokenEventListener = publisher -> publisher.registerHandlerFor(TestRunStarted.class,
374+
(TestRunStarted event) -> {
375+
throw expectedException;
376+
});
377+
378+
Executable testMethod = () -> Runtime.builder()
379+
.withFeatureSupplier(new StubFeatureSupplier())
380+
.withAdditionalPlugins(brokenEventListener)
381+
.build()
382+
.run();
383+
RuntimeException actualThrown = assertThrows(RuntimeException.class, testMethod);
384+
assertThat(actualThrown, equalTo(expectedException));
385+
}
386+
387+
@Test
388+
void should_fail_on_event_listener_exception_at_test_run_finished() {
389+
RuntimeException expectedException = new RuntimeException("This exception is expected");
390+
ConcurrentEventListener brokenEventListener = publisher -> publisher.registerHandlerFor(TestRunFinished.class,
391+
(TestRunFinished event) -> {
392+
throw expectedException;
393+
});
394+
395+
Executable testMethod = () -> Runtime.builder()
396+
.withFeatureSupplier(new StubFeatureSupplier())
397+
.withAdditionalPlugins(brokenEventListener)
398+
.build()
399+
.run();
400+
RuntimeException actualThrown = assertThrows(RuntimeException.class, testMethod);
401+
assertThat(actualThrown, equalTo(expectedException));
402+
}
403+
369404
@Test
370405
void should_interrupt_waiting_plugins() throws InterruptedException {
371406
final Feature feature1 = TestFeatureParser.parse("path/test.feature", "" +

pom.xml

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
<groupId>io.cucumber</groupId>
66
<artifactId>cucumber-parent</artifactId>
77
<version>4.1.1</version>
8+
<relativePath/>
89
</parent>
910
<artifactId>cucumber-jvm</artifactId>
1011
<version>7.10.0-SNAPSHOT</version>

0 commit comments

Comments
 (0)