Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixing bug with DataProvider retry #2822

Merged
merged 1 commit into from Nov 4, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
14 changes: 14 additions & 0 deletions testng-core/src/main/java/org/testng/internal/Parameters.java
Expand Up @@ -790,6 +790,7 @@ public static ParameterHolder handleParameters(
}

Iterator<Object[]> initParams = null;
RuntimeException thrownException;
do {

for (IDataProviderListener dataProviderListener : holder.getListeners()) {
Expand All @@ -808,18 +809,31 @@ public static ParameterHolder handleParameters(
fedInstance,
annotationFinder);
shouldRetry = false;
thrownException = null;
} catch (RuntimeException e) {
for (IDataProviderListener each : holder.getListeners()) {
each.onDataProviderFailure(testMethod, methodParams.context, e);
}
if (shouldRetry) {
shouldRetry = retry.retry(dataProviderMethod);
thrownException = e;
} else {
throw e;
}
}
} while (shouldRetry);

if (thrownException != null) {
// The only time when this will be true is when the following happens:
// 1. A Retry was involved with the data provider
// 2. The retry mechanism immediately returned false and thus causing
// a retry to not happen
// 3. Since a retry was not recommended the while loop would have exited but
// we still should have been failing the test since the data provider invocation
// failed.
throw thrownException;
}

for (IDataProviderListener dataProviderListener : holder.getListeners()) {
dataProviderListener.afterDataProviderExecution(
dataProviderMethod, testMethod, methodParams.context);
Expand Down
Expand Up @@ -42,6 +42,7 @@
import test.dataprovider.issue2565.SampleTestUsingSupplier;
import test.dataprovider.issue2819.DataProviderListenerForRetryAwareTests;
import test.dataprovider.issue2819.SimpleRetry;
import test.dataprovider.issue2819.TestClassFailingRetrySample;
import test.dataprovider.issue2819.TestClassSample;
import test.dataprovider.issue2819.TestClassUsingDataProviderRetrySample;
import test.dataprovider.issue2819.TestClassWithMultipleRetryImplSample;
Expand Down Expand Up @@ -88,6 +89,17 @@ public void testDataProviderRetryInstancesAreUniqueForEachDataDrivenTest() {
assertThat(listener.getAfterInvocations()).isEqualTo(2);
}

@Test(description = "GITHUB-2819")
public void testDataProviderRetryAbortsGracefullyWhenNoRetryAtFirstTime() {
TestNG testng = create(TestClassFailingRetrySample.class);
DataProviderListenerForRetryAwareTests listener = new DataProviderListenerForRetryAwareTests();
testng.addListener(listener);
testng.run();
assertThat(listener.getBeforeInvocations()).isEqualTo(1);
assertThat(listener.getFailureInvocations()).isEqualTo(1);
assertThat(listener.getAfterInvocations()).isEqualTo(0);
}

@Test(description = "GITHUB-2800")
public void testDataProviderFromAbstractClassWhenCoupledWithFactories() {
InvokedMethodNameListener listener = run(test.dataprovider.issue2800.TestClassGenerator.class);
Expand Down
@@ -0,0 +1,25 @@
package test.dataprovider.issue2819;

import org.testng.IDataProviderMethod;
import org.testng.IRetryDataProvider;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;

public class TestClassFailingRetrySample {

@Test(dataProvider = "dp")
public void testMethod(int ignored) {}

@DataProvider(name = "dp", retryUsing = DonotRetry.class)
public Object[][] getData() {
throw new RuntimeException("problem");
}

public static class DonotRetry implements IRetryDataProvider {

@Override
public boolean retry(IDataProviderMethod dataProvider) {
return false;
}
}
}