Bird
Raised Fist0
Selenium Javatesting~15 mins

Data providers for parameterization in Selenium Java - Build an Automation Script

Choose your learning style10 modes available
Login functionality test with multiple user credentials
Preconditions (2)
Step 1: Navigate to 'https://example.com/login'.
Step 2: For each set of credentials:
Step 3: - Enter the username in the username input field with id 'username'.
Step 4: - Enter the password in the password input field with id 'password'.
Step 5: - Click the login button with id 'loginBtn'.
Step 6: - Verify the login result:
Step 7: * If credentials are valid, verify the URL changes to 'https://example.com/dashboard'.
Step 8: * If credentials are invalid, verify an error message with id 'errorMsg' is displayed.
✅ Expected Result: The login succeeds for valid credentials and the dashboard page is shown. For invalid credentials, an error message is displayed.
Automation Requirements - TestNG with Selenium WebDriver
Assertions Needed:
Verify URL after login attempt matches expected URL for valid credentials.
Verify error message is displayed for invalid credentials.
Best Practices:
Use @DataProvider annotation to supply multiple sets of credentials.
Use explicit waits to wait for page load or error message visibility.
Use Page Object Model to separate page interactions from test logic.
Use meaningful assertion messages.
Automated Solution
Selenium Java
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.

Common Mistakes - 4 Pitfalls
Hardcoding credentials inside the test method instead of using @DataProvider
Using Thread.sleep() instead of explicit waits
Not clearing input fields before sending keys
Using brittle locators like absolute XPath
Bonus Challenge

Now add data-driven testing with 3 different sets of user credentials including edge cases like empty username or password.

Show Hint

Practice

(1/5)
1. What is the main purpose of using a @DataProvider in Selenium Java tests?
easy
A. To run the same test multiple times with different input data
B. To create a new browser instance for each test
C. To skip tests that are not ready
D. To generate reports automatically after tests

Solution

  1. Step 1: Understand the role of @DataProvider

    @DataProvider supplies different sets of data to a test method, enabling multiple runs with varied inputs.
  2. 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.
  3. Final Answer:

    To run the same test multiple times with different input data -> Option A
  4. Quick Check:

    @DataProvider = multiple test runs with varied data [OK]
Hint: DataProvider runs tests repeatedly with different inputs [OK]
Common Mistakes:
  • Thinking @DataProvider creates new browsers
  • Confusing @DataProvider with test skipping
  • Assuming it generates reports automatically
2. Which of the following is the correct syntax to declare a DataProvider method in Selenium Java?
easy
A. @DataProvider public void dataProviderMethod() { }
B. @Test(dataProvider = "testData") public void dataProviderMethod() { }
C. @DataProvider(name = "testData") public void dataProviderMethod() { }
D. @DataProvider(name = "testData") public Object[][] dataProviderMethod() { return new Object[][] {{"data1"}, {"data2"}}; }

Solution

  1. Step 1: Check the method signature for DataProvider

    A DataProvider method must return Object[][] and be annotated with @DataProvider(name = "...").
  2. 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.
  3. Final Answer:

    @DataProvider(name = "testData") public Object[][] dataProviderMethod() { return new Object[][] {{"data1"}, {"data2"}}; } -> Option D
  4. Quick Check:

    DataProvider method returns Object[][] [OK]
Hint: DataProvider methods return Object[][] with @DataProvider annotation [OK]
Common Mistakes:
  • Using void return type for DataProvider
  • Missing the name attribute in @DataProvider
  • Annotating test method instead of DataProvider method
3. Given the following code snippet, what will be the output when the test runs?
@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);
}
medium
A. No output because test is skipped
B. 1 and 2 printed on separate lines
C. 3 and 7 printed on separate lines
D. Compilation error due to wrong DataProvider

Solution

  1. Step 1: Understand the DataProvider data

    The DataProvider returns two sets: {1, 2} and {3, 4}.
  2. Step 2: Calculate the sum for each test run

    First run: 1 + 2 = 3; second run: 3 + 4 = 7; both printed on separate lines.
  3. Final Answer:

    3 and 7 printed on separate lines -> Option C
  4. Quick Check:

    Sum of pairs = 3, 7 [OK]
Hint: Sum each data pair printed per test run [OK]
Common Mistakes:
  • Assuming only one test run happens
  • Confusing data sets with single values
  • Expecting compilation errors without syntax issues
4. Identify the error in the following DataProvider usage:
@DataProvider(name = "inputData")
public Object[] data() {
    return new Object[] {"A", "B"};
}

@Test(dataProvider = "inputData")
public void testMethod(String input) {
    System.out.println(input);
}
medium
A. DataProvider method should return Object[][], not Object[]
B. Test method parameter type is incorrect
C. Missing @Test annotation on DataProvider method
D. DataProvider name does not match test method

Solution

  1. Step 1: Check DataProvider return type

    DataProvider methods must return Object[][] to supply multiple parameter sets.
  2. Step 2: Identify mismatch in return type

    The method returns Object[], which is invalid and causes runtime errors.
  3. Final Answer:

    DataProvider method should return Object[][], not Object[] -> Option A
  4. Quick Check:

    DataProvider return type = Object[][] [OK]
Hint: DataProvider must return Object[][], not Object[] [OK]
Common Mistakes:
  • Returning Object[] instead of Object[][]
  • Confusing test method parameter types
  • Forgetting to match DataProvider name
5. You want to test a login form with multiple username and password combinations using a DataProvider. Which approach correctly handles this scenario to avoid test failures when a password is empty or null?
@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
}
hard
A. Remove entries with empty or null passwords from DataProvider
B. Add validation inside testLogin to skip or handle empty/null passwords
C. Change DataProvider to return only usernames without passwords
D. Use separate test methods for each username-password pair

Solution

  1. Step 1: Recognize the need to handle edge cases in test method

    Empty or null passwords can cause test failures if not handled properly.
  2. Step 2: Implement validation inside testLogin method

    Adding checks to skip or handle empty/null passwords prevents failures and tests robustness.
  3. Final Answer:

    Add validation inside testLogin to skip or handle empty/null passwords -> Option B
  4. Quick Check:

    Handle edge cases inside test method [OK]
Hint: Validate inputs inside test to handle empty or null values [OK]
Common Mistakes:
  • Removing test data instead of handling it
  • Ignoring null or empty values causing failures
  • Splitting tests unnecessarily instead of parameterizing
Recommended

Ready to prove it?

Pass the test and this pattern moves unknown strong while earning +1 Grip toward your certificate.

10 questions~5 mineasy hard