-
Notifications
You must be signed in to change notification settings - Fork 1k
Closed
Milestone
Description
TestNG Version
7.0.0
Also reproducible on:
6.14.3, 7.0.0beta1
Expected behavior
The test should be in Skipped status.
A checked exception occurred in DataProvider should be handled.
Actual behavior
java.lang.NullPointerException
at java.util.Objects.requireNonNull(Objects.java:203)
at org.testng.internal.TestInvoker.retryFailed(TestInvoker.java:192)
at org.testng.internal.MethodRunner.runInSequence(MethodRunner.java:58)
at org.testng.internal.TestInvoker$MethodInvocationAgent.invoke(TestInvoker.java:804)
at org.testng.internal.TestInvoker.invokeTestMethods(TestInvoker.java:145)
at org.testng.internal.TestMethodWorker.invokeTestMethods(TestMethodWorker.java:146)
at org.testng.internal.TestMethodWorker.run(TestMethodWorker.java:128)
at java.util.ArrayList.forEach(ArrayList.java:1255)
at org.testng.TestRunner.privateRun(TestRunner.java:770)
at org.testng.TestRunner.run(TestRunner.java:591)
at org.testng.SuiteRunner.runTest(SuiteRunner.java:402)
at org.testng.SuiteRunner.runSequentially(SuiteRunner.java:396)
at org.testng.SuiteRunner.privateRun(SuiteRunner.java:355)
at org.testng.SuiteRunner.run(SuiteRunner.java:304)
at org.testng.SuiteRunnerWorker.runSuite(SuiteRunnerWorker.java:53)
at org.testng.SuiteRunnerWorker.run(SuiteRunnerWorker.java:96)
at org.testng.TestNG.runSuitesSequentially(TestNG.java:1180)
at org.testng.TestNG.runSuitesLocally(TestNG.java:1102)
at org.testng.TestNG.runSuites(TestNG.java:1032)
at org.testng.TestNG.run(TestNG.java:1000)
at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.runTests(TestNGTestClassProcessor.java:139)
at org.gradle.api.internal.tasks.testing.testng.TestNGTestClassProcessor.stop(TestNGTestClassProcessor.java:89)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.stop(SuiteTestClassProcessor.java:61)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy2.stop(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.stop(TestWorker.java:131)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:155)
at org.gradle.internal.remote.internal.hub.MessageHubBackedObjectConnection$DispatchWrapper.dispatch(MessageHubBackedObjectConnection.java:137)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:404)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:63)
at org.gradle.internal.concurrent.ManagedExecutorImpl$1.run(ManagedExecutorImpl.java:46)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at org.gradle.internal.concurrent.ThreadFactoryImpl$ManagedThreadRunnable.run(ThreadFactoryImpl.java:55)
at java.lang.Thread.run(Thread.java:748)
Is the issue reproductible on runner?
- Shell
- Maven
- Gradle
- Ant
- Eclipse
- IntelliJ
- NetBeans
Test case sample
The test case is implemented in the project below.
https://github.com/OstapJ/testng-issue-retry-dataprovider
The test with Retry and DataProvider
import org.testng.annotations.Test;
import java.util.concurrent.atomic.AtomicInteger;
public class RetryTest {
private AtomicInteger counter = new AtomicInteger();
@Test(description = "Nullpointer occurs when Retried test has exception is DataProvider",
dataProviderClass = DP.class, dataProvider = "dpWithException",
groups = {"issue"}, retryAnalyzer = RetryImpl.class
)
void testExample(String value) {
counter.getAndIncrement();
if(counter.get() == 1){
assert value.isEmpty();
}
if(counter.get() == 2){
assert value.isEmpty();
}
}
}DataProvider with exception
import org.testng.annotations.DataProvider;
import java.util.concurrent.atomic.AtomicInteger;
public class DP {
private static AtomicInteger counter = new AtomicInteger();
@DataProvider
public static Object[][] dpWithException() {
return new Object[][]{
{foo()},
};
}
private static String foo(){
counter.getAndIncrement();
if(counter.get() == 1){
return "First";
}
if(counter.get() == 2){
return "Second";
}
throw new RuntimeException("TestNG doesn't handle an exception");
}
}import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;
import java.util.Arrays;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicInteger;
public class RetryImpl implements IRetryAnalyzer {
private static final Logger LOG = LoggerFactory.getLogger(RetryImpl.class);
private final Map<Integer, AtomicInteger> counts = new ConcurrentHashMap<>();
private AtomicInteger getCount(ITestResult result) {
int id = Arrays.hashCode((result.getTestClass().getName() + result.getName() + result.getMethod().getParameterInvocationCount()).getBytes());
AtomicInteger count = counts.get(id);
if (count == null) {
count = new AtomicInteger(3);
counts.put(id, count);
}
return count;
}
@Override
public boolean retry(ITestResult result) {
int retriesRemaining = getCount(result).getAndDecrement();
return retriesRemaining > 0;
}
}Metadata
Metadata
Assignees
Labels
No labels