-
-
Notifications
You must be signed in to change notification settings - Fork 1.6k
Description
Steps to reproduce
Given an arbitrary suite with a failing before suite hook.
@Suite
@SelectPackages("com.example")
public class RunCucumberTest {
@BeforeSuite
static void before(){
throw new RuntimeException("Oops");
}
@AfterSuite
static void after(){
}
}
The trimmed stacktrace is:
java.lang.RuntimeException: Oops
at io.cucumber.skeleton.RunCucumberTest.before(RunCucumberTest.java:21)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.accept(ForEachOps.java:184)
at java.base/java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:197)
at java.base/java.util.Iterator.forEachRemaining(Iterator.java:133)
at java.base/java.util.Spliterators$IteratorSpliterator.forEachRemaining(Spliterators.java:1939)
at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
at java.base/java.util.stream.ForEachOps$ForEachOp.evaluateSequential(ForEachOps.java:151)
at java.base/java.util.stream.ForEachOps$ForEachOp$OfRef.evaluateSequential(ForEachOps.java:174)
at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.base/java.util.stream.ReferencePipeline.forEach(ReferencePipeline.java:596)
While I would expect only:
java.lang.RuntimeException: Oops
at io.cucumber.skeleton.RunCucumberTest.before(RunCucumberTest.java:21)
Likewise
public class ExampleTest {
@BeforeAll
static void beforeAll(){
throw new RuntimeException("Oops");
}
@Test
void test(){
}
}
Prints a slightly too long stacktrace:
java.lang.RuntimeException: Oops
at io.cucumber.prettyformatter.ExampleTest.beforeAll(ExampleTest.java:10)
at java.base/java.lang.reflect.Method.invoke(Method.java:580)
at java.base/java.util.ArrayList.forEach(ArrayList.java:1596)
To support engines whos children are tests, it would also be good to include both self and ancestors when looking for prune limits in StackTracePruningEngineExecutionListener
. But I couldn't reproduce the issues mentioned in #4825, with any existing Engine implementation. They all have containers as children.
Solution:
private static List<String> getTestClassNames(TestDescriptor testDescriptor) {
var self = Stream.of(testDescriptor);
var ancestors = testDescriptor.getAncestors().stream();
return Stream.concat(self, ancestors) //
.map(TestDescriptor::getSource) //
.flatMap(Optional::stream) //
.map(source -> {
if (source instanceof ClassSource classSource) {
return classSource.getClassName();
}
else if (source instanceof MethodSource methodSource) {
return methodSource.getClassName();
}
else {
return null;
}
}) //
.filter(Objects::nonNull) //
.toList();
}
Context
Did a small investigation following the discussion in #4825 and found this instead.
- Version: 5.13.4, 6.0.0-SNAPSHOT @ fc94772
Deliverables
- Slightly more pruned stacktraces
- Include both self and ancestors in
getTestClassNames
for test that don't use containers.