ScreenshotNeo

BlogGuides

TestNG Parameterization: DataProvider and XML Examples

Learn when to use TestNG XML parameters or @DataProvider, with runnable Java and XML examples, scope rules, parallel settings, troubleshooting, and command-line overrides.

By the ScreenshotNeo team4 October 20268 min read

Use TestNG XML parameters for a small number of named settings that configure a test run. Use @DataProvider when the same test method should run with multiple sets of test-case data. XML values are matched to method arguments by names declared in @Parameters; provider rows supply arguments by position.

This guide shows both approaches, explains scope and defaults, and covers parallel data providers, command-line overrides, and common errors.

1. Choose XML parameters or a data provider

Question Use XML parameters Use @DataProvider
What does the input represent? A named run setting, such as an environment or browser. A test case or row of inputs for repeated test invocations.
Where do values live? In testng.xml, with optional JVM system-property overrides. In Java code returned by a provider method.
How do values map to arguments? Names in @Parameters map to method arguments in annotation order. Each provider row maps positionally to the test method arguments.
How many invocations? Usually one invocation configured for a run. One invocation per returned row or iterator element.
Parallel data execution? Not the defining feature. Opt in with parallel=true on the provider.

For example, choose XML for a test that should target a selected environment, and a data provider for a login test that should exercise several account and password combinations.

2. Pass a named setting with TestNG XML

In this example, the suite defines an environment parameter. The test method requests that name and supplies a fallback of staging if the parameter is absent.

package example;

import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import org.testng.annotations.Test;

public class EnvironmentTest {
  @Test
  @Parameters("environment")
  public void usesConfiguredEnvironment(@Optional("staging") String environment) {
    System.out.println("Environment: " + environment);
    // Use the selected environment when configuring the system under test.
  }
}

Save the suite configuration as testng.xml. Its class name must match the package and class in the Java source:

<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Environment suite">
  <parameter name="environment" value="qa"/>
  <test name="Environment checks">
    <classes>
      <class name="example.EnvironmentTest"/>
    </classes>
  </test>
</suite>

With this configuration, the method receives qa. If no value named environment is available in the applicable XML scope, @Optional("staging") provides the fallback. See the official TestNG parameters documentation.

Multiple named parameters

List parameter names in the same order as the corresponding Java arguments. Each XML name must match a name in the annotation.

@Test
@Parameters({"environment", "browser"})
public void opensConfiguredTarget(String environment, String browser) {
  System.out.println(environment + " on " + browser);
}
<test name="Browser checks">
  <parameter name="environment" value="qa"/>
  <parameter name="browser" value="firefox"/>
  <classes>
    <class name="example.EnvironmentTest"/>
  </classes>
</test>

TestNG converts XML parameter values to the types required by the method when supported. For predictable configuration, keep XML values simple and verify that the method signature and supplied values agree. Consult the documentation for supported types and behavior relevant to your TestNG version.

3. Supply repeated cases with @DataProvider

A provider returns test data, and the test names it with dataProvider. Each inner array is one invocation’s argument list.

package example;

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

public class LoginTest {
  @DataProvider(name = "credentials")
  public Object[][] credentials() {
    return new Object[][] {
      {"reader", "correct-password"},
      {"locked-user", "any-password"}
    };
  }

  @Test(dataProvider = "credentials")
  public void loginCases(String username, String password) {
    System.out.println("Checking login for " + username);
    // Exercise the login behavior for this row.
  }
}

The test method runs once for each row. Argument count and order must line up: the first value goes to username, and the second goes to password. The provider name in @Test must match the provider’s declared name. If you omit name from @DataProvider, the annotated provider method’s name is used.

Lazy data with an iterator

For cases generated as they are consumed, a provider can return an iterator instead. For multiple test arguments, TestNG 7.9.0 documents Iterator<Object[]> as a supported shape.

import java.util.Arrays;
import java.util.Iterator;
import org.testng.annotations.DataProvider;

@DataProvider(name = "cases")
public Iterator<Object[]> cases() {
  return Arrays.asList(
      new Object[] {"reader", "correct-password"},
      new Object[] {"locked-user", "any-password"}
  ).iterator();
}

The TestNG 7.9.0 API lists Object[][] and Iterator<Object[]> for multiple arguments, and Object[] and Iterator<Object> for a single argument. Check the API documentation for the TestNG version in your build: TestNG 7.9.0 DataProvider API.

4. Understand XML parameter scope and defaults

TestNG permits XML parameters at suite, test, class, and methods scope. A more specific declaration takes precedence over a broader declaration with the same name. In practice, method scope can override a class, test, or suite value; class scope can override a test or suite value; and test scope can override a suite value.

  • Suite scope: a broad default for tests in the suite.
  • Test scope: a value for classes grouped under one <test>.
  • Class scope: a value for a particular class.
  • Methods scope: a value for a particular method.

Put a shared setting at the broadest scope that is correct, then override it only where a test needs a different value. Use @Optional on a parameter to provide a fallback when the XML value is not present. A fallback is not a substitute for a correctly named XML parameter when the run must use a specific setting.

5. Override XML values with JVM system properties

TestNG documents that JVM system properties can override values declared in testng.xml. This is useful when the same suite configuration should run against different environments from a build command. The system property is still configuration for a run; it does not generate the multiple data rows that a provider supplies.

For example, pass a property while starting the JVM with your normal build or test runner:

mvn test -Denvironment=qa

Use the property name expected by your TestNG configuration and build setup. The exact invocation and how your build selects testng.xml depend on the project configuration. Refer to TestNG’s parameter documentation for the system-property behavior and XML setup.

6. Run data-provider cases in parallel

Data-provider execution is not parallel by default. Set parallel=true on the provider to opt in:

@DataProvider(name = "credentials", parallel = true)
public Object[][] credentials() {
  return new Object[][] {
    {"reader", "correct-password"},
    {"locked-user", "any-password"}
  };
}

The TestNG documentation describes a default thread-pool size of 10 for parallel data providers invoked from XML, adjustable with the suite’s data-provider-thread-count setting. For example:

<suite name="Parallel checks" data-provider-thread-count="4">
  <test name="Login cases">
    <classes>
      <class name="example.LoginTest"/>
    </classes>
  </test>
</suite>

TestNG 7.9.0 added suite-level share-thread-pool-for-data-providers and use-global-thread-pool controls. The 7.9.0 documentation points to the testng-1.1.dtd for these attributes. These options are version-sensitive, so check the DTD and documentation for the version actually used by your build before adding them. See the TestNG documentation and the versioned DataProvider API.

Parallel calls can expose shared mutable state: for example, cases that modify the same account or reuse a non-thread-safe object. Design cases to be independent, and make setup and cleanup safe under concurrent execution. A thread pool setting controls concurrency; it does not make test data or application state isolated automatically.

7. Troubleshoot common parameterization errors

Symptom Likely cause Fix
TestNG reports that a parameter is missing. The XML name is absent from the active scope, misspelled, or not available to that test. Check the spelling and placement of <parameter>. Add @Optional only if a default is valid for the test.
The method receives an unexpected value. A broader or more specific scope supplied a value that takes precedence, or a JVM system property overrode the XML value. Inspect suite, test, class, and method declarations, then check the test process’s system properties.
Arguments appear in the wrong variables. Multiple @Parameters names or provider row values are in a different order than the method signature. Align annotation order and Java arguments, or reorder each provider row.
The data provider cannot be found. The dataProvider name does not match the provider name, or the provider is not visible in the expected context. Match the annotation names exactly. For a provider in another class, use the supported provider-class configuration for your TestNG version.
Provider invocation fails with an argument or type error. A row has the wrong number of values or a value incompatible with the test method argument. Check every row against the test signature and use the documented provider return shape.
Parallel runs fail intermittently. Cases share mutable fixtures, external records, or other state that is not safe for concurrent access. Isolate case data and resources, or disable provider parallelism while making the cases independent.
A suite rejects a pool attribute. The attribute is not supported by the TestNG or DTD version selected by the project. Check the version and DTD. The shared/global pool controls are documented from TestNG 7.9.0.

8. Keep parameterized suites fast and reliable

  • Use the right input shape. Keep run configuration in named XML parameters and case variation in data-provider rows. This makes failures easier to associate with the configured run or specific case.
  • Keep rows independent. Independent cases are easier to parallelize and retry without order-dependent failures.
  • Choose concurrency deliberately. Parallelism may reduce elapsed test time when cases can run concurrently, but it increases simultaneous resource use. Start with a thread count your test environment can support.
  • Use lazy iteration when useful. An iterator can generate cases as they are consumed instead of assembling all cases in an array first.
  • Check the actual dependency version. Pool controls and API details can vary by TestNG version. Confirm the version resolved by your build and use its matching documentation.

9. Capture screenshots from test workflows

ScreenshotNeo is a website screenshot API and MCP server for developers, made by Yorker Media. A TestNG suite can call an HTTP API when a test workflow needs a page screenshot; see the ScreenshotNeo site and API documentation for request details.

Or skip the browser setup

Use one GET request to capture a URL as an image or PDF. For example, save a WebP screenshot with cURL:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

ScreenshotNeo accepts cookie or consent banners like a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Create a free ScreenshotNeo account to get 1,000 screenshots a month with no card.

10. Frequently asked questions

Can one TestNG test use both XML parameters and a data provider?

They serve different input roles. Keep run-level configuration in XML parameters and case arguments in a provider when both are needed, and check the test method signature and TestNG version for the supported combination.

Should passwords or other secrets go in testng.xml?

Avoid committing secrets in test configuration files. Supply sensitive values through your build or secret-management process, and ensure they are not printed by tests or logs.

Does a data provider need to return every case at once?

No. TestNG documents iterator return forms as well as arrays, including Iterator<Object[]> for multiple arguments.

Where can I check details for my TestNG release?

Use the official TestNG documentation and the API documentation matching the version resolved by your project. The parameter page and API references can change over time.