Skip to content

Early engine failure throws NoSuchElementException and masks root exception #202

@westse

Description

@westse

The only failure mode is:

org.junit.platform.commons.JUnitException: TestEngine with ID 'testng' failed to execute tests
Caused by: java.util.NoSuchElementException

Setting a debug breakpoint in NoSuchElementException shows the following.

"Test worker@1" tid=0x1 nid=NA runnable
  java.lang.Thread.State: RUNNABLE
   at java.util.NoSuchElementException.<init>(NoSuchElementException.java:45)
   at java.util.Spliterators$1Adapter.next(Spliterators.java:688)
   at org.junit.support.testng.engine.ExecutionListener.chain(ExecutionListener.java:240)
   at org.junit.support.testng.engine.ExecutionListener.abortedOrFailed(ExecutionListener.java:230)
   at org.junit.support.testng.engine.ExecutionListener.toTestExecutionResult(ExecutionListener.java:225)
   at org.junit.support.testng.engine.ExecutionListener.lambda$onAfterClass$3(ExecutionListener.java:93)
   at org.junit.support.testng.engine.ExecutionListener$$Lambda/0x00007f88ac7b4248.accept(Unknown Source:-1)
   at org.junit.support.testng.engine.TestClassRegistry.lambda$finish$2(TestClassRegistry.java:53)
   at org.junit.support.testng.engine.TestClassRegistry$$Lambda/0x00007f88ac61b058.apply(Unknown Source:-1)
   at java.util.concurrent.ConcurrentHashMap.compute(ConcurrentHashMap.java:1940)
   - locked <0x241d> (a java.util.concurrent.ConcurrentHashMap$Node)
   at org.junit.support.testng.engine.TestClassRegistry.finish(TestClassRegistry.java:47)
   at org.junit.support.testng.engine.ExecutionListener.onAfterClass(ExecutionListener.java:89)
   at org.testng.internal.invokers.TestMethodWorker.invokeListenersOnAfterClass(TestMethodWorker.java:235)
   at org.testng.internal.invokers.TestMethodWorker.invokeAfterClassMethods(TestMethodWorker.java:214)
   at org.testng.internal.invokers.TestMethodWorker.run(TestMethodWorker.java:131)
... 

This indicates that ExecutionListener.chain() is calling iterator.next() blindly without guarding with an if (iterator.hasNext()){...}. The assumption of the caller (abortedOrFailed()) is that all aborted or failed results will have a throwable. It appears this logic is invoked not only for @Test methods but also for @BeforeMethod methods, and in this case a throwable is not available when there is an early engine failure (e.g. in @BeforeSuite, @BeforeTest, etc).

Metadata

Metadata

Labels

bugSomething isn't working

Type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions