TestNG has a second way to pass data to tests: the @Parameters annotation. It reads values from testng.xml. Unlike DataProvider (which feeds multiple data sets), @Parameters passes a single value per parameter. It is best for environment-level settings like browser type, base URL, or environment name.
| @Parameters (testng.xml) | @DataProvider (Java) |
|---|---|
| One value per parameter — test runs once | Multiple rows — test runs N times |
| Values defined in testng.xml | Values from Java code or external files |
| Best for: browser, URL, environment name | Best for: login combos, search terms, form data |
| Configured by QA lead or DevOps | Configured by test automation engineer |
| Cannot iterate over multiple data sets | Each row is a separate test execution |
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Cross Browser Suite" parallel="tests"
thread-count="2">
<test name="Chrome Tests">
<parameter name="browser" value="chrome" />
<parameter name="baseUrl"
value="https://www.testerrank.com" />
<classes>
<class name="com.practice.tests.banking.LoginTests" />
<class name="com.practice.tests.shopping.CatalogTests" />
<class name="com.practice.tests.insurance.QuoteTests" />
</classes>
</test>
<test name="Firefox Tests">
<parameter name="browser" value="firefox" />
<parameter name="baseUrl"
value="https://www.testerrank.com" />
<classes>
<class name="com.practice.tests.banking.LoginTests" />
<class name="com.practice.tests.shopping.CatalogTests" />
<class name="com.practice.tests.insurance.QuoteTests" />
</classes>
</test>
</suite>import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Optional;
import org.testng.annotations.Parameters;
import java.time.Duration;
public class BaseTest {
protected WebDriver driver;
protected String baseUrl;
@BeforeMethod
@Parameters({"browser", "baseUrl"})
public void setUp(
@Optional("chrome") String browser,
@Optional("https://www.testerrank.com")
String baseUrl) {
this.baseUrl = baseUrl;
switch (browser.toLowerCase()) {
case "firefox":
FirefoxOptions ffOptions =
new FirefoxOptions();
driver = new FirefoxDriver(ffOptions);
break;
case "edge":
driver = new org.openqa.selenium
.edge.EdgeDriver();
break;
case "chrome":
default:
ChromeOptions chromeOptions =
new ChromeOptions();
driver = new ChromeDriver(chromeOptions);
break;
}
driver.manage().window().maximize();
driver.manage().timeouts().implicitlyWait(
Duration.ofSeconds(5));
driver.get(baseUrl);
}
protected void navigateTo(String path) {
driver.get(baseUrl + path);
}
@AfterMethod
public void tearDown() {
if (driver != null) {
driver.quit();
}
}
}The @Optional annotation is critical. Without it, running a test directly from your IDE (without testng.xml) throws an exception because the parameters are not available. @Optional provides fallback values so the test works both ways — from IDE and from testng.xml.
<!-- testng-staging.xml -->
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "https://testng.org/testng-1.0.dtd">
<suite name="Staging Regression">
<test name="Staging Chrome">
<parameter name="browser" value="chrome" />
<parameter name="baseUrl"
value="https://staging.testerrank.com" />
<classes>
<class name="com.practice.tests.banking.LoginTests" />
<class name="com.practice.tests.banking.TransferTests" />
<class name="com.practice.tests.shopping.CatalogTests" />
</classes>
</test>
</suite>
<!-- Run with: mvn test -DsuiteXmlFile=testng-staging.xml -->Q: What is the difference between @DataProvider and @Parameters in TestNG?
A: @DataProvider returns multiple data sets (Object[][]) and runs the test once per set — ideal for data-driven testing with many input combinations. @Parameters reads single values from testng.xml — ideal for environment-level configuration like browser type or base URL. In our framework, we use @Parameters for cross-browser setup in BaseTest and @DataProvider for test data in individual test classes.
If you use @Parameters without @Optional and forget to run via testng.xml, TestNG throws org.testng.TestNGException: Parameter "browser" is required. Always add @Optional with sensible defaults.
Key Point: @Parameters passes single values from testng.xml. Always use @Optional for IDE compatibility.