Data providers for parameterization in Selenium Java - Build an Automation Script
import org.openqa.selenium.By; import org.openqa.selenium.WebDriver; import org.openqa.selenium.WebElement; import org.openqa.selenium.chrome.ChromeDriver; import org.openqa.selenium.support.ui.ExpectedConditions; import org.openqa.selenium.support.ui.WebDriverWait; import org.testng.Assert; import org.testng.annotations.AfterClass; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; import org.testng.annotations.Test; import java.time.Duration; public class LoginTest { private WebDriver driver; private WebDriverWait wait; @BeforeClass public void setUp() { driver = new ChromeDriver(); wait = new WebDriverWait(driver, Duration.ofSeconds(10)); } @DataProvider(name = "loginData") public Object[][] loginData() { return new Object[][] { {"validUser1", "validPass1", true}, {"validUser2", "validPass2", true}, {"invalidUser", "wrongPass", false} }; } @Test(dataProvider = "loginData") public void testLogin(String username, String password, boolean isValid) { driver.get("https://example.com/login"); WebElement usernameInput = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("username"))); usernameInput.clear(); usernameInput.sendKeys(username); WebElement passwordInput = driver.findElement(By.id("password")); passwordInput.clear(); passwordInput.sendKeys(password); WebElement loginButton = driver.findElement(By.id("loginBtn")); loginButton.click(); if (isValid) { boolean urlChanged = wait.until(ExpectedConditions.urlToBe("https://example.com/dashboard")); Assert.assertTrue(urlChanged, "Expected to be on dashboard page after valid login."); } else { WebElement errorMsg = wait.until(ExpectedConditions.visibilityOfElementLocated(By.id("errorMsg"))); Assert.assertTrue(errorMsg.isDisplayed(), "Error message should be displayed for invalid login."); } } @AfterClass public void tearDown() { if (driver != null) { driver.quit(); } } }
This test class uses Selenium WebDriver with TestNG to automate login tests with multiple credentials.
setUp(): Initializes ChromeDriver and WebDriverWait before tests.
@DataProvider loginData(): Supplies three sets of username, password, and a boolean indicating if credentials are valid.
testLogin(): Runs once per data set. It navigates to the login page, enters username and password, clicks login, then verifies the result:
- If credentials are valid, waits until URL changes to dashboard and asserts success.
- If invalid, waits for error message visibility and asserts it is shown.
tearDown(): Closes the browser after all tests.
Explicit waits ensure elements are ready before interaction. Assertions have clear messages to help understand failures. Using @DataProvider allows easy parameterization of tests.
Now add data-driven testing with 3 different sets of user credentials including edge cases like empty username or password.
Practice
@DataProvider in Selenium Java tests?Solution
Step 1: Understand the role of @DataProvider
@DataProvider supplies different sets of data to a test method, enabling multiple runs with varied inputs.Step 2: Identify the main benefit
This helps find bugs that appear only with certain inputs by running the same test repeatedly with different data.Final Answer:
To run the same test multiple times with different input data -> Option AQuick Check:
@DataProvider = multiple test runs with varied data [OK]
- Thinking @DataProvider creates new browsers
- Confusing @DataProvider with test skipping
- Assuming it generates reports automatically
Solution
Step 1: Check the method signature for DataProvider
A DataProvider method must return Object[][] and be annotated with @DataProvider(name = "...").Step 2: Verify the return type and annotation
@DataProvider(name = "testData") public Object[][] dataProviderMethod() { return new Object[][] {{"data1"}, {"data2"}}; } correctly returns Object[][] and uses the proper annotation with a name.Final Answer:
@DataProvider(name = "testData") public Object[][] dataProviderMethod() { return new Object[][] {{"data1"}, {"data2"}}; } -> Option DQuick Check:
DataProvider method returns Object[][] [OK]
- Using void return type for DataProvider
- Missing the name attribute in @DataProvider
- Annotating test method instead of DataProvider method
@DataProvider(name = "numbers")
public Object[][] data() {
return new Object[][] { {1, 2}, {3, 4} };
}
@Test(dataProvider = "numbers")
public void testSum(int a, int b) {
System.out.println(a + b);
}Solution
Step 1: Understand the DataProvider data
The DataProvider returns two sets: {1, 2} and {3, 4}.Step 2: Calculate the sum for each test run
First run: 1 + 2 = 3; second run: 3 + 4 = 7; both printed on separate lines.Final Answer:
3 and 7 printed on separate lines -> Option CQuick Check:
Sum of pairs = 3, 7 [OK]
- Assuming only one test run happens
- Confusing data sets with single values
- Expecting compilation errors without syntax issues
@DataProvider(name = "inputData")
public Object[] data() {
return new Object[] {"A", "B"};
}
@Test(dataProvider = "inputData")
public void testMethod(String input) {
System.out.println(input);
}Solution
Step 1: Check DataProvider return type
DataProvider methods must return Object[][] to supply multiple parameter sets.Step 2: Identify mismatch in return type
The method returns Object[], which is invalid and causes runtime errors.Final Answer:
DataProvider method should return Object[][], not Object[] -> Option AQuick Check:
DataProvider return type = Object[][] [OK]
- Returning Object[] instead of Object[][]
- Confusing test method parameter types
- Forgetting to match DataProvider name
@DataProvider(name = "loginData")
public Object[][] loginData() {
return new Object[][] {
{"user1", "pass1"},
{"user2", ""},
{"user3", null}
};
}
@Test(dataProvider = "loginData")
public void testLogin(String username, String password) {
// Test logic here
}Solution
Step 1: Recognize the need to handle edge cases in test method
Empty or null passwords can cause test failures if not handled properly.Step 2: Implement validation inside testLogin method
Adding checks to skip or handle empty/null passwords prevents failures and tests robustness.Final Answer:
Add validation inside testLogin to skip or handle empty/null passwords -> Option BQuick Check:
Handle edge cases inside test method [OK]
- Removing test data instead of handling it
- Ignoring null or empty values causing failures
- Splitting tests unnecessarily instead of parameterizing
Ready to prove it?
Pass the test and this pattern moves unknown
