Data Providers in TestNG
Data Provider is one of the most important features of TestNG used for executing the same test method multiple times with different sets of test data. Instead of writing separate test methods for every input value, a Data Provider supplies multiple data sets to a single test method.
Data Providers are especially useful in Selenium automation frameworks for testing login credentials, search values, user roles, form inputs, product details, checkout information, and other scenarios where the same functionality needs to be tested with different data.
In TestNG, the @DataProvider annotation is used to create a method that returns test data. The test method then receives this data through the dataProvider attribute of the @Test annotation.
Course Resource: Selenium Training | Register for Course Demo
1. What is a Data Provider?
A Data Provider is a TestNG mechanism that allows a test method to receive multiple sets of data. The same test method is executed once for each row of data returned by the Data Provider.
For example, suppose a login page needs to be tested with five different username and password combinations. Without a Data Provider, we might create five separate test cases. With a Data Provider, we can create one test method and provide five different data sets.
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class LoginTest {
@DataProvider(name = "loginData")
public Object[][] getLoginData() {
return new Object[][] {
{"user1", "pass123"},
{"user2", "pass456"},
{"user3", "pass789"}
};
}
@Test(dataProvider = "loginData")
public void loginTest(String username, String password) {
System.out.println("Username: " + username);
System.out.println("Password: " + password);
}
}
2. Why is Data Provider Important?
Data Providers are important because automation testing frequently requires the same test scenario to be executed against different input values.
- Reduces duplicate test code.
- Allows one test method to execute with multiple data sets.
- Improves test maintainability.
- Supports data-driven testing.
- Makes test cases easier to expand.
- Separates test logic from test data.
- Works effectively with Selenium WebDriver.
- Can be combined with Page Object Model.
- Can be used for positive and negative test scenarios.
- Supports parameterized execution without creating multiple test methods.
3. Data Provider Flow
The basic execution flow of a TestNG Data Provider is:
TestNG starts execution
|
v
@DataProvider method
|
v
Returns multiple data sets
|
v
@Test method receives one data set
|
v
Test executes
|
v
Next data set is supplied
|
v
@Test executes again
|
v
All data sets completed
4. Data-Driven Testing
Data-driven testing is a testing approach where test logic remains the same while test data changes for different executions.
For example, a login test may use the same login workflow for multiple combinations:
| Username | Password | Expected Result |
| validUser | validPass | Login Successful |
| invalidUser | validPass | Invalid Username |
| validUser | invalidPass | Invalid Password |
| invalidUser | invalidPass | Login Failed |
The test logic remains the same, but the input data changes.
5. @DataProvider Annotation
The @DataProvider annotation identifies a method as a data provider.
@DataProvider(name = "testData")
public Object[][] getTestData() {
return new Object[][] {
{"value1"},
{"value2"},
{"value3"}
};
}
The name attribute gives the Data Provider a name that can be referenced from the test method.
6. Connecting @DataProvider with @Test
A test method can connect to a Data Provider by using the dataProvider attribute.
@Test(dataProvider = "testData")
public void testExample(String value) {
System.out.println(value);
}
Here, testData must match the name specified in the @DataProvider annotation.
7. Complete Basic Data Provider Example
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class DataProviderExample {
@DataProvider(name = "names")
public Object[][] getNames() {
return new Object[][] {
{"John"},
{"David"},
{"Michael"},
{"Robert"}
};
}
@Test(dataProvider = "names")
public void nameTest(String name) {
System.out.println("Testing name: " + name);
}
}
The test method executes four times because the Data Provider contains four rows.
8. Understanding Object[][]
Most Data Providers return an Object[][]. The two-dimensional array represents rows and columns of test data.
return new Object[][] {
{"John", "India"},
{"David", "USA"},
{"Robert", "UK"}
};
In this example:
- There are 3 rows.
- There are 2 columns.
- Each row represents one test execution.
- Each column represents one parameter.
| Execution | Column 1 | Column 2 |
| 1 | John | India |
| 2 | David | USA |
| 3 | Robert | UK |
9. Data Provider with Multiple Parameters
A Data Provider can supply multiple values to the same test method.
@DataProvider(name = "userData")
public Object[][] getUserData() {
return new Object[][] {
{"John", "john123", "Admin"},
{"David", "david123", "User"},
{"Robert", "robert123", "Manager"}
};
}
@Test(dataProvider = "userData")
public void userTest(String username, String password, String role) {
System.out.println("Username: " + username);
System.out.println("Password: " + password);
System.out.println("Role: " + role);
}
The number and order of parameters in the test method should correspond to the values supplied by each Data Provider row.
10. Data Provider with Selenium WebDriver
Data Providers are frequently used with Selenium to execute browser automation tests with multiple input values.
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class LoginTest {
WebDriver driver;
@DataProvider(name = "loginData")
public Object[][] loginData() {
return new Object[][] {
{"user1", "pass123"},
{"user2", "pass456"},
{"user3", "pass789"}
};
}
@Test(dataProvider = "loginData")
public void loginTest(String username, String password) {
driver = new ChromeDriver();
driver.get("https://example.com/login");
driver.findElement(By.id("username")).sendKeys(username);
driver.findElement(By.id("password")).sendKeys(password);
driver.findElement(By.id("loginButton")).click();
}
@AfterMethod
public void closeBrowser() {
if (driver != null) {
driver.quit();
}
}
}
Each row of the Data Provider causes a separate execution of the login test.
11. Data Provider for Login Testing
Login automation is one of the most common practical applications of Data Providers.
@DataProvider(name = "loginData")
public Object[][] loginData() {
return new Object[][] {
{"admin", "admin123"},
{"manager", "manager123"},
{"employee", "employee123"},
{"invalid", "wrong123"}
};
}
@Test(dataProvider = "loginData")
public void loginTest(String username, String password) {
System.out.println("Testing login for: " + username);
}
12. Data Provider for Positive and Negative Testing
Data Providers can be used to test both valid and invalid inputs.
@DataProvider(name = "loginScenarios")
public Object[][] loginScenarios() {
return new Object[][] {
{"validUser", "validPass", "success"},
{"invalidUser", "validPass", "invalid username"},
{"validUser", "invalidPass", "invalid password"},
{"", "", "required fields"}
};
}
@Test(dataProvider = "loginScenarios")
public void loginValidationTest(
String username,
String password,
String expectedResult) {
System.out.println("Testing: " + expectedResult);
}
13. Data Provider for Search Testing
Search functionality can also be tested using multiple search terms.
@DataProvider(name = "searchData")
public Object[][] searchData() {
return new Object[][] {
{"Laptop"},
{"Mobile"},
{"Headphones"},
{"Keyboard"},
{"Mouse"}
};
}
@Test(dataProvider = "searchData")
public void searchTest(String searchText) {
System.out.println("Searching for: " + searchText);
}
14. Data Provider for Form Testing
Forms often contain multiple input fields. A Data Provider can supply complete form data.
@DataProvider(name = "registrationData")
public Object[][] registrationData() {
return new Object[][] {
{"John", "[email protected]", "9876543210"},
{"David", "[email protected]", "9876543211"},
{"Robert", "[email protected]", "9876543212"}
};
}
@Test(dataProvider = "registrationData")
public void registrationTest(
String name,
String email,
String mobile) {
System.out.println(name);
System.out.println(email);
System.out.println(mobile);
}
15. Data Provider with Expected Results
Expected results can also be included in the Data Provider.
@DataProvider(name = "calculatorData")
public Object[][] calculatorData() {
return new Object[][] {
{10, 20, 30},
{5, 5, 10},
{100, 50, 150}
};
}
@Test(dataProvider = "calculatorData")
public void additionTest(int a, int b, int expected) {
int actual = a + b;
System.out.println("Expected: " + expected);
System.out.println("Actual: " + actual);
}
16. Data Provider with Assertions
Data Providers can supply both input data and expected values to assertion-based tests.
import org.testng.Assert;
@DataProvider(name = "additionData")
public Object[][] additionData() {
return new Object[][] {
{10, 20, 30},
{5, 5, 10},
{100, 25, 125}
};
}
@Test(dataProvider = "additionData")
public void additionTest(int a, int b, int expected) {
int actual = a + b;
Assert.assertEquals(actual, expected);
}
17. Data Provider Returning Different Data Types
A Data Provider can return different Java data types because it uses the Object type.
@DataProvider(name = "mixedData")
public Object[][] mixedData() {
return new Object[][] {
{"John", 25, true},
{"David", 30, false},
{"Robert", 28, true}
};
}
@Test(dataProvider = "mixedData")
public void mixedDataTest(String name, int age, boolean active) {
System.out.println(name);
System.out.println(age);
System.out.println(active);
}
18. Data Provider with String Values
@DataProvider(name = "stringData")
public Object[][] stringData() {
return new Object[][] {
{"Chrome"},
{"Firefox"},
{"Edge"}
};
}
@Test(dataProvider = "stringData")
public void browserTest(String browser) {
System.out.println("Browser: " + browser);
}
19. Data Provider with Integer Values
@DataProvider(name = "numberData")
public Object[][] numberData() {
return new Object[][] {
{10},
{20},
{30},
{40}
};
}
@Test(dataProvider = "numberData")
public void numberTest(int number) {
System.out.println(number);
}
20. Data Provider with Boolean Values
@DataProvider(name = "booleanData")
public Object[][] booleanData() {
return new Object[][] {
{true},
{false}
};
}
@Test(dataProvider = "booleanData")
public void booleanTest(boolean value) {
System.out.println("Value: " + value);
}
21. Data Provider in a Separate Class
Data Providers can be placed in another class and reused by multiple test classes.
public class TestData {
@DataProvider(name = "loginData")
public Object[][] loginData() {
return new Object[][] {
{"admin", "admin123"},
{"user", "user123"}
};
}
}
The test class can reference the external Data Provider using the dataProviderClass attribute.
public class LoginTest {
@Test(
dataProvider = "loginData",
dataProviderClass = TestData.class
)
public void loginTest(String username, String password) {
System.out.println(username);
}
}
22. Reusing Data Providers
Reusable Data Providers are useful in large automation frameworks. Instead of duplicating test data in every class, common data can be maintained in a dedicated test-data class.
public class CommonDataProvider {
@DataProvider(name = "users")
public Object[][] users() {
return new Object[][] {
{"admin", "admin123"},
{"manager", "manager123"},
{"employee", "employee123"}
};
}
}
23. Data Provider with Page Object Model
Data Providers work very well with the Page Object Model (POM). The Data Provider supplies the data while the Page Object contains the application interaction logic.
public class LoginPage {
WebDriver driver;
By username = By.id("username");
By password = By.id("password");
By loginButton = By.id("loginButton");
public LoginPage(WebDriver driver) {
this.driver = driver;
}
public void login(String user, String pass) {
driver.findElement(username).sendKeys(user);
driver.findElement(password).sendKeys(pass);
driver.findElement(loginButton).click();
}
}
The test class can use the Data Provider to supply multiple login combinations.
24. POM with Data Provider Example
public class LoginTest {
WebDriver driver;
LoginPage loginPage;
@DataProvider(name = "loginData")
public Object[][] loginData() {
return new Object[][] {
{"admin", "admin123"},
{"manager", "manager123"},
{"employee", "employee123"}
};
}
@Test(dataProvider = "loginData")
public void loginTest(String username, String password) {
loginPage = new LoginPage(driver);
loginPage.login(username, password);
}
}
25. Data Provider vs @Parameters
Both @DataProvider and @Parameters support parameterized testing, but they are designed for different purposes.
| Feature | @DataProvider | @Parameters |
| Primary Purpose | Multiple test data sets | Configuration parameters |
| Data Source | Java method | testng.xml |
| Repeated Execution | Yes | Not inherently |
| Best For | Data-driven testing | Browser, URL, environment |
| Multiple Rows | Yes | Not directly |
| External Data | Can be loaded by Java code | Can be configured through XML |
26. Data Provider vs Hard-Coded Test Data
| Hard-Coded Data | Data Provider |
| Data mixed with test logic | Data separated from test logic |
| More duplicate code | Less duplicate code |
| Harder to maintain | Easier to maintain |
| Less scalable | More scalable |
| Adding data may require code changes | New rows can be added easily |
27. Data Provider and Excel Data
A Data Provider can read test data from an Excel file and return it to the test method. Apache POI is commonly used in Java Selenium frameworks for reading Excel files.
@DataProvider(name = "excelData")
public Object[][] excelData() {
// Excel reading logic can be implemented here.
return new Object[][] {
{"user1", "pass1"},
{"user2", "pass2"},
{"user3", "pass3"}
};
}
In a production framework, the Data Provider can read rows and columns dynamically from an Excel workbook.
28. Data Provider and CSV Data
CSV files can also be used as an external source for test data. The Data Provider reads the file and converts each row into an Object array.
@DataProvider(name = "csvData")
public Object[][] csvData() {
// CSV reading logic can be implemented here.
return new Object[][] {
{"John", "[email protected]"},
{"David", "[email protected]"}
};
}
29. Data Provider and Database Data
Large automation frameworks may retrieve test data from a database. A Data Provider can execute a database query, read the returned records, and provide them to the test method.
@DataProvider(name = "databaseData")
public Object[][] databaseData() {
// Database connection and query logic
// can be implemented here.
return new Object[][] {
{"user1", "active"},
{"user2", "inactive"}
};
}
30. Data Provider with JSON Data
JSON is another common source for test data, especially in API and modern UI automation frameworks. Java code can read JSON data and convert it into objects that can be supplied through a Data Provider.
@DataProvider(name = "jsonData")
public Object[][] jsonData() {
return new Object[][] {
{"Chrome", "https://example.com"},
{"Firefox", "https://example.com"}
};
}
31. Data Provider with Configuration Methods
Data Providers can be combined with TestNG configuration methods such as @BeforeMethod, @BeforeClass, and @AfterMethod.
@BeforeMethod
public void setup() {
System.out.println("Browser setup");
}
@DataProvider(name = "users")
public Object[][] users() {
return new Object[][] {
{"user1"},
{"user2"}
};
}
@Test(dataProvider = "users")
public void testUser(String username) {
System.out.println("Testing: " + username);
}
@AfterMethod
public void tearDown() {
System.out.println("Closing browser");
}
32. Execution Order with Data Provider
When a test uses a Data Provider, TestNG invokes the test method for each row of data.
@DataProvider(name = "data")
public Object[][] data() {
return new Object[][] {
{"A"},
{"B"},
{"C"}
};
}
@Test(dataProvider = "data")
public void test(String value) {
System.out.println(value);
}
Conceptually, the execution is:
test("A")
test("B")
test("C")
33. Number of Executions
The number of test executions normally corresponds to the number of rows returned by the Data Provider.
Object[][] data = {
{"A"},
{"B"},
{"C"},
{"D"}
};
Therefore, the test method will receive four data sets and execute four times.
34. Data Provider with Browser Testing
A Data Provider can supply browser names when the same test needs to run against multiple browsers.
@DataProvider(name = "browsers")
public Object[][] browsers() {
return new Object[][] {
{"chrome"},
{"firefox"},
{"edge"}
};
}
@Test(dataProvider = "browsers")
public void browserTest(String browser) {
System.out.println("Running test on: " + browser);
}
For complete cross-browser execution, the browser value can be passed to a WebDriver factory or browser initialization method.
35. Data Provider with Environment Testing
Test data can represent different application environments.
@DataProvider(name = "environments")
public Object[][] environments() {
return new Object[][] {
{"QA", "https://qa.example.com"},
{"Stage", "https://stage.example.com"},
{"Production", "https://www.example.com"}
};
}
@Test(dataProvider = "environments")
public void environmentTest(String environment, String url) {
System.out.println(environment + " : " + url);
}
36. Data Provider for User Roles
Applications frequently have multiple roles such as Admin, Manager, Employee, and Customer. A Data Provider can test role-based functionality.
@DataProvider(name = "roles")
public Object[][] roles() {
return new Object[][] {
{"admin"},
{"manager"},
{"employee"},
{"customer"}
};
}
@Test(dataProvider = "roles")
public void roleTest(String role) {
System.out.println("Testing role: " + role);
}
37. Data Provider for E-Commerce Testing
E-commerce applications contain many data-driven scenarios such as products, quantities, discount codes, payment methods, and shipping details.
@DataProvider(name = "productData")
public Object[][] productData() {
return new Object[][] {
{"Laptop", 1},
{"Mobile", 2},
{"Headphones", 3}
};
}
@Test(dataProvider = "productData")
public void productTest(String product, int quantity) {
System.out.println(product + " - " + quantity);
}
38. Data Provider for Search Filters
@DataProvider(name = "filters")
public Object[][] filters() {
return new Object[][] {
{"Laptop", "Electronics"},
{"Shoes", "Fashion"},
{"Book", "Books"}
};
}
@Test(dataProvider = "filters")
public void filterTest(String keyword, String category) {
System.out.println(keyword);
System.out.println(category);
}
39. Data Provider with Multiple Test Methods
The same Data Provider can be reused by multiple test methods within a class.
@DataProvider(name = "users")
public Object[][] users() {
return new Object[][] {
{"admin"},
{"manager"}
};
}
@Test(dataProvider = "users")
public void loginTest(String username) {
System.out.println("Login: " + username);
}
@Test(dataProvider = "users")
public void profileTest(String username) {
System.out.println("Profile: " + username);
}
40. Data Provider with External Class
Large projects commonly maintain Data Providers separately from test classes.
public class LoginDataProvider {
@DataProvider(name = "loginData")
public Object[][] loginData() {
return new Object[][] {
{"admin", "admin123"},
{"manager", "manager123"}
};
}
}
Test class:
public class LoginTest {
@Test(
dataProvider = "loginData",
dataProviderClass = LoginDataProvider.class
)
public void loginTest(String username, String password) {
System.out.println(username);
}
}
41. Data Provider with Parallel Execution
TestNG can execute Data Provider test invocations in parallel. This can reduce execution time when tests are independent and the automation framework is designed for thread safety.
@DataProvider(
name = "users",
parallel = true
)
public Object[][] users() {
return new Object[][] {
{"user1"},
{"user2"},
{"user3"},
{"user4"}
};
}
@Test(dataProvider = "users")
public void userTest(String username) {
System.out.println(
Thread.currentThread().getId() + " : " + username
);
}
Parallel execution should be used carefully with Selenium because WebDriver instances should not be shared unsafely between concurrent test invocations.
42. Data Provider and Thread Safety
When Data Provider tests run in parallel, each test should generally have its own WebDriver instance and isolated test data.
A common framework design is:
Data Provider
|
v
Test Invocation
|
v
Thread-specific WebDriver
|
v
Browser Session
|
v
Test Execution
Using shared static WebDriver instances in parallel tests can cause interference between test cases.
43. Data Provider with Method Parameters
TestNG also supports advanced Data Provider usage where a Data Provider can receive information about the method requesting the data.
@DataProvider(name = "methodData")
public Object[][] methodData(Method method) {
System.out.println("Executing method: " + method.getName());
return new Object[][] {
{"Test Data"}
};
}
@Test(dataProvider = "methodData")
public void sampleTest(String data) {
System.out.println(data);
}
44. Data Provider with ITestContext
TestNG provides context information that can be used in advanced framework designs.
@DataProvider(name = "contextData")
public Object[][] contextData(ITestContext context) {
System.out.println(
"Suite: " + context.getSuite().getName()
);
return new Object[][] {
{"Sample Data"}
};
}
45. Data Provider with Factory
TestNG also provides a @Factory mechanism for creating test instances dynamically. Data Providers and factories solve different problems, although they can be used together in advanced frameworks.
- DataProvider: Supplies data to test method invocations.
- Factory: Creates test class instances.
46. Data Provider vs Factory
| DataProvider | Factory |
| Supplies test data | Creates test instances |
| Usually executes one method with multiple data sets | Creates multiple object instances |
| Useful for data-driven testing | Useful for dynamic test creation |
47. Data Provider and Assertions
Assertions should be used to verify the actual application result against the expected result supplied by the Data Provider.
@DataProvider(name = "loginResults")
public Object[][] loginResults() {
return new Object[][] {
{"validUser", "validPass", "Dashboard"},
{"invalidUser", "wrongPass", "Login Error"}
};
}
@Test(dataProvider = "loginResults")
public void loginTest(
String username,
String password,
String expectedPage) {
String actualPage = expectedPage;
Assert.assertEquals(actualPage, expectedPage);
}
48. Data Provider with TestNG Reports
Each Data Provider invocation can appear as a separate test execution in TestNG reports. This makes it easier to identify which particular data set passed or failed.
For example:
LoginTest
|
|-- admin / admin123 PASS
|-- manager / manager123 PASS
|-- invalid / wrong123 FAIL
Frameworks can additionally include the input data in logs or reports, while avoiding exposure of sensitive values such as passwords.
49. Handling Sensitive Data
Passwords, API keys, tokens, and other secrets should not normally be stored as plain text in source-controlled Data Provider code.
For sensitive test data, consider using secure configuration or secret-management mechanisms appropriate to the project.
For example, a Data Provider can obtain non-sensitive test identifiers from configuration and retrieve credentials securely at runtime.
50. Data Provider and Maven Execution
Data Provider tests can be executed using Maven like any other TestNG tests.
mvn test
Maven can be integrated with Selenium and TestNG frameworks to execute automated test suites in local and CI environments.
51. Data Provider in CI/CD
Data Providers are useful in CI/CD pipelines because the same automation logic can execute against many test data combinations automatically.
Developer Commit
|
v
CI/CD Pipeline
|
v
Build
|
v
TestNG
|
v
@DataProvider
|
v
Multiple Test Executions
|
v
Selenium WebDriver
|
v
Test Report
52. Data Provider for Regression Testing
Regression suites often contain tests that need to run against multiple combinations of inputs. Data Providers make such tests easier to maintain.
For example, an application search regression test can use different keywords, categories, filters, and expected results without creating separate test methods.
53. Common Mistakes with Data Providers
- Using the wrong Data Provider name.
- Mismatch between Data Provider columns and test parameters.
- Returning an incorrect array structure.
- Using null data without handling it properly.
- Sharing WebDriver instances between parallel tests.
- Hard-coding sensitive credentials.
- Putting too much business logic inside the Data Provider.
- Creating extremely large in-memory data sets.
- Not identifying which data set caused a failure.
- Using Data Providers when simple configuration parameters would be more appropriate.
54. Data Provider Name Mismatch
The name referenced by the test must match the Data Provider name.
Incorrect:
@DataProvider(name = "loginData")
public Object[][] getData() {
return new Object[][] {
{"user", "pass"}
};
}
@Test(dataProvider = "userData")
public void loginTest(String username, String password) {
}
Correct:
@Test(dataProvider = "loginData")
public void loginTest(String username, String password) {
}
55. Parameter Count Mismatch
The number of values supplied in each Data Provider row should match the parameters expected by the test method.
For example, if the Data Provider supplies three values:
{"John", "[email protected]", "India"}
The test method should accept three compatible parameters:
@Test(dataProvider = "data")
public void test(
String name,
String email,
String country) {
}
56. Best Practices for Data Providers
- Keep test data separate from test logic where practical.
- Use meaningful Data Provider names.
- Keep each Data Provider focused on a logical test-data purpose.
- Use external data sources for large or frequently changing data sets.
- Avoid hard-coding secrets.
- Use reusable Data Provider classes in larger frameworks.
- Use assertions with expected values from the Data Provider.
- Make test data readable and maintainable.
- Use parallel Data Providers only when the framework is thread-safe.
- Log enough information to identify failed data sets without exposing secrets.
- Use POM to keep Selenium interaction logic separate from test data.
57. Practical Project Structure
A scalable Selenium TestNG framework can organize Data Providers separately.
src
|-- test
|-- java
|-- tests
| |-- LoginTest.java
| |-- SearchTest.java
| |-- CheckoutTest.java
|
|-- pages
| |-- LoginPage.java
| |-- SearchPage.java
| |-- CheckoutPage.java
|
|-- data
| |-- LoginDataProvider.java
| |-- SearchDataProvider.java
| |-- ProductDataProvider.java
|
|-- utilities
|-- DriverFactory.java
|-- ExcelReader.java
|-- ConfigReader.java
58. Complete Practical Login Project
The following example demonstrates a basic Selenium TestNG framework using a Data Provider for multiple login combinations.
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.testng.Assert;
import org.testng.annotations.AfterMethod;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
public class LoginTest {
WebDriver driver;
@BeforeMethod
public void setup() {
driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://example.com/login");
}
@DataProvider(name = "loginData")
public Object[][] loginData() {
return new Object[][] {
{"admin", "admin123"},
{"manager", "manager123"},
{"employee", "employee123"}
};
}
@Test(dataProvider = "loginData")
public void loginTest(String username, String password) {
driver.findElement(By.id("username"))
.sendKeys(username);
driver.findElement(By.id("password"))
.sendKeys(password);
driver.findElement(By.id("loginButton"))
.click();
Assert.assertTrue(
driver.getTitle().contains("Dashboard")
);
}
@AfterMethod
public void tearDown() {
if (driver != null) {
driver.quit();
}
}
}
59. Real-World Data Provider Architecture
Test Data
|
+-----------+-----------+
| | |
Excel JSON DB
| | |
+-----------+-----------+
|
v
Data Provider
|
v
Test Method
|
v
Page Objects
|
v
Selenium WebDriver
|
v
Application
|
v
Assertions
|
v
Report
60. Advantages of Data Providers
- Code Reusability: The same test method can be executed with many data sets.
- Maintainability: Test data can be managed separately from test logic.
- Scalability: Additional data sets can be added easily.
- Reduced Duplication: Multiple similar test methods are not required.
- Better Coverage: More input combinations can be tested.
- Integration: Data Providers can work with Selenium, POM, Maven, CI/CD, and reporting tools.
- Parallel Execution: Data Provider invocations can be executed in parallel when appropriate.
61. Limitations of Data Providers
- Very large data sets can consume significant memory when loaded into Object arrays.
- Complex external data handling may require additional utilities.
- Parallel execution requires thread-safe framework design.
- Incorrect parameter mapping can cause runtime failures.
- Debugging can become difficult if test data is not clearly identified.
- Data Providers may not be the best choice for simple environment configuration.
62. Data Provider vs XML Parameter vs Configuration
| Feature | DataProvider | @Parameters | Configuration |
| Main Purpose | Test data | Configuration values | Test setup/cleanup |
| Multiple Data Sets | Yes | Limited | No |
| Source | Java/external data | XML | Java/XML context |
| Typical Use | Login/search/form data | Browser/URL/environment | Setup/teardown |
63. Interview Questions on Data Providers
1. What is a Data Provider in TestNG?
A Data Provider is a TestNG feature that supplies multiple sets of test data to a test method.
2. Which annotation is used for Data Providers?
The @DataProvider annotation is used.
3. How does a test method use a Data Provider?
The test method uses the dataProvider attribute of the @Test annotation.
4. What does Object[][] represent?
It represents multiple rows of test data where each row is supplied to one test invocation.
5. Can a Data Provider provide multiple parameters?
Yes. Each row can contain multiple values that map to parameters of the test method.
6. Can a Data Provider be placed in another class?
Yes. The dataProviderClass attribute can be used to reference an external Data Provider class.
7. Can Data Providers be used with Selenium?
Yes. They are commonly used for Selenium login, search, registration, checkout, and other data-driven tests.
8. Can Data Providers read Excel data?
Yes. Java libraries such as Apache POI can be used to read Excel data and return it through a Data Provider.
9. Can Data Providers execute tests in parallel?
Yes. The Data Provider can be configured with parallel = true.
10. What is the difference between DataProvider and @Parameters?
DataProvider is primarily used for multiple test data sets, while @Parameters is commonly used for configuration values supplied through TestNG XML.
11. Can Data Providers supply expected results?
Yes. Expected results can be included as additional columns in each data row.
12. Can a Data Provider return different data types?
Yes. Because the return type commonly uses Object[][], different compatible Java data types can be supplied.
13. Can one Data Provider be used by multiple tests?
Yes. A Data Provider can be reused by multiple test methods.
14. Why is Data Provider useful in regression testing?
It allows the same regression test logic to be executed against many input combinations.
15. What happens if the parameter count does not match?
TestNG can report an error because the values supplied by the Data Provider do not correctly map to the test method parameters.
16. Can Data Providers be used with Page Object Model?
Yes. Data Providers can supply data while Page Objects handle Selenium interactions.
17. Can Data Providers use database data?
Yes. Database queries can be executed and their results can be converted into Data Provider data.
18. What is the main benefit of Data Providers?
The major benefit is executing reusable test logic against multiple data sets without duplicating the test method.
19. Should passwords be hard-coded in Data Providers?
Sensitive credentials should generally be managed securely rather than stored as plain text in source-controlled test code.
20. What is a common mistake when using Data Providers?
Common mistakes include Data Provider name mismatches, incorrect parameter counts, incompatible data types, and unsafe WebDriver sharing during parallel execution.
64. Quick Reference Table
| Concept | Description |
| @DataProvider | Defines a test-data provider |
| dataProvider | Connects a test method to a Data Provider |
| dataProviderClass | References a Data Provider in another class |
| Object[][] | Common structure for multiple rows and columns of data |
| parallel = true | Allows Data Provider invocations to run in parallel |
| Data-driven testing | Same test logic with different data |
| POM | Separates page interaction logic from test logic |
| Excel | Can be used as an external data source |
| CSV | Can provide external test data |
| Database | Can provide dynamically retrieved test data |
65. Learning Roadmap for Data Providers
- Understand TestNG basics.
- Learn the @DataProvider annotation.
- Understand Object[][].
- Create a single-column Data Provider.
- Create multiple-column Data Providers.
- Connect Data Providers with @Test.
- Use Data Providers with Selenium.
- Use Data Providers with assertions.
- Combine Data Providers with Page Object Model.
- Move Data Providers into reusable classes.
- Read data from Excel, CSV, JSON, or databases.
- Learn parallel Data Provider execution.
- Build a reusable data-driven Selenium framework.
- Integrate the framework with Maven and CI/CD.
66. Practical Exercises
- Create a Data Provider containing five usernames.
- Create a login test using username and password combinations.
- Create a search test using ten search keywords.
- Create a registration test using name, email, and mobile number.
- Create a calculator test using input and expected result values.
- Create a browser Data Provider for Chrome, Firefox, and Edge.
- Create a Data Provider for Admin, Manager, and Employee roles.
- Read test data from Excel using Apache POI.
- Create a reusable Data Provider class.
- Execute Data Provider tests in parallel.
- Integrate the Data Provider framework with Page Object Model.
67. Real-World Example
Consider an e-commerce website where a QA engineer needs to test product search for several products.
@DataProvider(name = "products")
public Object[][] products() {
return new Object[][] {
{"Laptop"},
{"Mobile"},
{"Tablet"},
{"Headphones"},
{"Keyboard"}
};
}
@Test(dataProvider = "products")
public void productSearchTest(String product) {
driver.findElement(By.id("search"))
.clear();
driver.findElement(By.id("search"))
.sendKeys(product);
driver.findElement(By.id("searchButton"))
.click();
System.out.println(
"Searching product: " + product
);
}
Instead of creating five separate test methods, one reusable test method handles all five product searches.
68. Data Provider Best-Practice Architecture
External Test Data
|
v
Data Reader / Utility
|
v
@DataProvider
|
v
TestNG Test Method
|
v
Page Object Model
|
v
Selenium WebDriver
|
v
Application
|
v
Assertions
|
v
Reports
69. Summary
TestNG Data Providers are a powerful feature for implementing data-driven testing. They allow one test method to execute multiple times using different input values.
In Selenium automation, Data Providers can be used for login credentials, search keywords, registration details, products, browser combinations, user roles, environments, expected results, and many other test scenarios.
The basic implementation consists of creating a method with @DataProvider, returning test data such as Object[][], and connecting that method to a @Test method using the dataProvider attribute.
For larger frameworks, Data Providers can be combined with Page Object Model, external test-data files, database utilities, Maven, CI/CD pipelines, parallel execution, reporting, and reusable framework components.
70. Course Resources
Learn more about Selenium automation and related testing concepts:
Final Takeaway: Data Providers make TestNG tests reusable, scalable, and data-driven by separating test execution logic from the input data. They are especially valuable when the same Selenium workflow needs to be validated against many different test-data combinations.