Skip to content

Commit

Permalink
Handle exceptions from data provider
Browse files Browse the repository at this point in the history
Closes #2157
  • Loading branch information
krmahadevan committed Oct 2, 2019
1 parent ef05341 commit eb8144d
Show file tree
Hide file tree
Showing 5 changed files with 83 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
Current
Fixed: GITHUB-2157: NullPointerException occurs when a Retried test has an exception in DataProvider (Krishnan Mahadevan)
Fixed: GITHUB-2150: Upgraded jQuery from 1.7.1 to 3.4.1 to resolve reported prototype pollution vulnerability
Fixed: GITHUB-2149: Handle NoClassDefFoundError when classloader fails to load a class
New: GITHUB-2111: Provide an interceptor for Data Provider (Krishnan Mahadevan)
Expand Down
11 changes: 11 additions & 0 deletions src/main/java/org/testng/DataProviderInvocationException.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package org.testng;

/**
* Represents any issues that arise out of invoking a data provider method.
*/
public class DataProviderInvocationException extends TestNGException {

public DataProviderInvocationException(String string, Throwable t) {
super(string, t);
}
}
9 changes: 9 additions & 0 deletions src/main/java/org/testng/internal/TestInvoker.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import org.testng.DataProviderHolder;
import org.testng.DataProviderInvocationException;
import org.testng.IClassListener;
import org.testng.IDataProviderListener;
import org.testng.IHookable;
Expand Down Expand Up @@ -188,6 +189,14 @@ public FailureContext retryFailed(

ParameterBag bag = handler.createParameters(arguments.getTestMethod(),
arguments.getParameters(), allParameters, testContext);
ITestResult errorResult = bag.errorResult;

if (errorResult != null ) {
Throwable cause = errorResult.getThrowable();
String m = errorResult.getMethod().getMethodName();
String msg = String.format("Encountered problems when gathering parameter values for [%s]. Root cause: ", m);
throw new DataProviderInvocationException(msg, cause);
}
Object[] parameterValues =
Parameters.getParametersFromIndex(Objects.requireNonNull(bag.parameterHolder).parameters,
arguments.getParametersIndex());
Expand Down
12 changes: 12 additions & 0 deletions src/test/java/test/dataprovider/FailingDataProviderTest.java
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
package test.dataprovider;

import org.testng.DataProviderInvocationException;
import org.testng.ITestResult;
import org.testng.annotations.Test;
import test.InvokedMethodNameListener;
import test.SimpleBaseTest;
import test.dataprovider.issue2157.TestClassWithDataProviderThatThrowsExceptions;

import static org.assertj.core.api.Assertions.assertThat;

Expand Down Expand Up @@ -33,4 +36,13 @@ public void failingDataProviderAndInvocationCount() {
"testShouldSkipEvenIfSuccessPercentage",
"testShouldSkipEvenIfSuccessPercentage");
}

@Test(description = "GITHUB-2157")
public void abortWhenDataProviderThrowsException() {
InvokedMethodNameListener listener = run(TestClassWithDataProviderThatThrowsExceptions.class);
ITestResult result = listener.getResult("testMethod");
Throwable cause = result.getThrowable();
assertThat(cause).isInstanceOf(DataProviderInvocationException.class);
assertThat(result.getStatus()).isEqualTo(ITestResult.FAILURE);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package test.dataprovider.issue2157;

import java.util.concurrent.atomic.AtomicInteger;
import org.testng.Assert;
import org.testng.IRetryAnalyzer;
import org.testng.ITestResult;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class TestClassWithDataProviderThatThrowsExceptions {

@Test(dataProvider = "dp", retryAnalyzer = SimplyRetry.class)
public void testMethod(String i) {
if ("First".equalsIgnoreCase(i) || "Second".equalsIgnoreCase(i)) {
Assert.fail();
}
}

private static AtomicInteger counter = new AtomicInteger();

@DataProvider(name = "dp")
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");
}

public static class SimplyRetry implements IRetryAnalyzer {

private static int attempts = 1;

@Override
public boolean retry(ITestResult result) {
return attempts++ != 3;
}
}

}

0 comments on commit eb8144d

Please # to comment.