How to Use TestNG DataProviders with Examples
Use TestNG DataProviders to run one test method with multiple input sets. Learn provider placement, reuse, parallel execution, and troubleshooting.
A TestNG DataProvider supplies arguments to a test method so the same test can run once for each input row. Mark a method with @DataProvider, then name it in the test’s @Test(dataProvider = "...") annotation. In the basic form, each inner array is one invocation, and its values map to the test method’s parameters by position.
1. Create a DataProvider and consume its rows
This example shows the core pattern. Replace the comment in the test with the behavior you want to exercise.
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class LoginTest {
@DataProvider(name = "credentials")
public Object[][] credentials() {
return new Object[][] {
{"alice", "correct-horse"},
{"bob", "battery-staple"}
};
}
@Test(dataProvider = "credentials")
public void loginAcceptsCredentials(String username, String password) {
// Exercise the behavior under test here.
}
}
When TestNG invokes loginAcceptsCredentials, it passes the first row’s values as username and password, then invokes the method again with the second row. The method’s parameter count and types should match the values in every row. The official TestNG documentation introduces this pattern with an Object[][] provider. See TestNG documentation.
2. Choose where provider data lives
Keep a provider in the test class
For a small set of test-specific cases, keeping the provider beside the test makes the relationship easy to see. If dataProviderClass is omitted, TestNG looks for the named provider in the test class or a base class.
Reuse a provider from another class
Use dataProviderClass when provider code belongs in a separate class. The provider method in that specified class must be static.
import org.testng.annotations.DataProvider;
public class CommonTestData {
@DataProvider(name = "usernames")
public static Object[][] usernames() {
return new Object[][] {
{"alice"},
{"bob"}
};
}
}
import org.testng.annotations.Test;
public class UsernameTest {
@Test(dataProvider = "usernames", dataProviderClass = CommonTestData.class)
public void usernameIsPresent(String username) {
// Exercise the behavior under test here.
}
}
Splitting providers out can make shared cases easier to maintain. Keep data local when it is only meaningful to one test; shared providers should remain understandable to every test that consumes them.
3. Reuse one provider for different test methods
A provider can accept a java.lang.reflect.Method. TestNG supplies the test method that is requesting data, which lets the provider choose rows based on the consumer.
import java.lang.reflect.Method;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class SharedProviderTest {
@DataProvider(name = "cases")
public Object[][] cases(Method testMethod) {
if (testMethod.getName().equals("checksShortNames")) {
return new Object[][] {{"Ada"}, {"Lin"}};
}
return new Object[][] {{"Grace Hopper"}};
}
@Test(dataProvider = "cases")
public void checksShortNames(String name) {
// Check the short-name case.
}
@Test(dataProvider = "cases")
public void checksFullName(String name) {
// Check the full-name case.
}
}
Use this when a shared provider genuinely needs to distinguish its consumers. If the cases are unrelated, separate providers are usually clearer and avoid accidental coupling to method names.
4. Run data-driven invocations in parallel
Parallel data-provider execution is opt-in. Set parallel = true on the provider. The TestNG documentation describes a default data-provider pool size of 10 for parallel data providers launched from an XML suite. Set data-provider-thread-count on the suite to change that pool size; provider thread-count settings take effect when parallel mode is selected.
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class ParallelTest {
@DataProvider(name = "values", parallel = true)
public Object[][] values() {
return new Object[][] {
{"first"},
{"second"},
{"third"}
};
}
@Test(dataProvider = "values")
public void processesValue(String value) {
// Each invocation may run concurrently with another.
}
}
<suite name="parallel-data" data-provider-thread-count="4">
<test name="tests">
<classes>
<class name="example.ParallelTest"/>
</classes>
</test>
</suite>
Parallelism can reduce elapsed time when each invocation does independent work, but it also makes shared mutable state and external resources more difficult to manage. Ensure each row can be processed safely alongside the others. The documentation’s pool-size description is specific to the stated XML-suite case; verify the settings against the TestNG version and suite DTD used by your project.
Shared pools in TestNG 7.9.0 and later
The documentation identifies two additional controls as available starting with TestNG 7.9.0:
share-thread-pool-for-data-providersshares a pool among data-driven tests in a suite. Its size is set withdata-provider-thread-count.use-global-thread-poolshares a pool for regular and data-driven tests, sized withthread-count.
These settings are version-bound. Confirm support and configuration in the documentation and DTD for the TestNG version installed in your project before using them.
5. Match the provider style to the problem
| Choice | Use it when | Trade-off |
|---|---|---|
| Provider beside the test | Data is specific to one test class. | Simple to follow, but not shared directly with unrelated classes. |
| Provider in a separate class | Several tests need common cases. | Reuse is easier; the specified provider method must be static. |
| Fixed rows | The cases are known and stable. | Readable and predictable; changes require editing the data. |
| Method-aware provider | One provider intentionally serves multiple tests with distinct cases. | Reduces duplication but couples selection to the requesting method. |
| Sequential execution | Tests share state or concurrency is unnecessary. | Less concurrency complexity; invocations do not overlap. |
| Parallel execution | Invocations are independent and the suite is configured for concurrency. | Can increase resource use and requires safe shared-state handling. |
6. Common errors and fixes
| Symptom | Likely cause | What to check |
|---|---|---|
| TestNG cannot find the provider | The name in @Test does not match the provider name, or the provider is not visible in the test class or its base class. |
Compare the strings exactly. If the provider is external, set dataProviderClass to its class. |
| External provider is rejected | The provider method in the class named by dataProviderClass is not static. |
Declare the provider method static. |
| Invocation fails with an argument or type mismatch | A row has a different number or type of values than the test method parameters expect. | Check every row, parameter order, and Java types. All rows should satisfy the same method signature. |
| Expected invocations do not appear | The provider returned fewer rows than expected, or the test is wired to a different provider name. | Inspect the returned rows and the dataProvider annotation value. |
| Parallel setting appears ineffective | parallel = true is absent, or suite/runner configuration does not select the expected mode. |
Check the provider annotation, suite XML, thread-count setting, TestNG version, and runner configuration. |
| Failures are intermittent under parallel execution | Invocations may be sharing mutable test data or another resource unsafely. | Give invocations independent state or protect shared resources; use sequential execution if the work cannot safely overlap. |
| A shared-pool option is unrecognized | The project may use a TestNG version older than 7.9.0 or a suite DTD that does not expose the setting. | Confirm the installed version and its matching configuration documentation. |
7. Practical notes on speed, reliability, and cost
- Speed: Parallel providers may allow independent invocations to overlap. The useful thread count depends on the workload and available resources; the documentation’s default of 10 is a configuration default for the described XML-suite case, not a performance guarantee.
- Reliability: Prefer deterministic rows and independent invocations. Parallel tests need careful treatment of shared state and external systems.
- Cost: DataProviders are a TestNG mechanism. Their direct cost is not a per-row TestNG charge; any cost comes from what the test invokes, such as infrastructure or external services. Track those resources separately when adding rows or concurrency.
- Compatibility: Basic provider patterns and version-specific pool options should be checked against the project’s installed TestNG release and suite configuration.
8. Or skip the browser setup
If a test workflow needs website screenshots, ScreenshotNeo is a website screenshot API and MCP server. Its API can return a screenshot or PDF from one GET request, and the parameter names used by other screenshot APIs also work.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for the request options. Cookie banners are accepted and removed before the shot, along with known newsletter popups and chat widgets; each cleanup step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Sign up free for 1,000 screenshots a month, with no card required.
9. FAQ
Does every DataProvider have to return Object[][]?
Object[][] is the basic documented example and a straightforward choice when each invocation takes multiple arguments. The cited documentation also describes DataProviders more generally as returning arrays of arrays of objects. Check the official documentation for other supported forms in your installed version.
Can a provider be inherited?
When dataProviderClass is omitted, TestNG looks for the named provider in the test class or a base class, so a provider can be placed in a base class.
Does parallel mode guarantee faster tests?
No. It permits concurrent data-driven invocations; actual elapsed time depends on the work, resource limits, and whether the invocations can safely overlap.
Where should I confirm suite settings?
Use the TestNG documentation and the suite DTD matching the TestNG version your project runs. In particular, confirm the version before relying on shared/global pool options introduced in 7.9.0.
Sources
Mechanics and configuration guidance in this article are based on the official TestNG documentation. Align examples and suite settings with your installed TestNG version.


