Data providers pattern in Selenium Python - Build an Automation Script
import unittest from selenium import webdriver from selenium.webdriver.common.by import By from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC class LoginPage: def __init__(self, driver): self.driver = driver self.url = 'https://example.com/login' self.username_input = (By.ID, 'username') self.password_input = (By.ID, 'password') self.login_button = (By.ID, 'loginBtn') self.error_message = (By.ID, 'errorMsg') def load(self): self.driver.get(self.url) def login(self, username, password): WebDriverWait(self.driver, 10).until( EC.visibility_of_element_located(self.username_input) ) self.driver.find_element(*self.username_input).clear() self.driver.find_element(*self.username_input).send_keys(username) self.driver.find_element(*self.password_input).clear() self.driver.find_element(*self.password_input).send_keys(password) self.driver.find_element(*self.login_button).click() def is_error_displayed(self): try: return WebDriverWait(self.driver, 5).until( EC.visibility_of_element_located(self.error_message) ) is not None except: return False class TestLogin(unittest.TestCase): @classmethod def setUpClass(cls): cls.driver = webdriver.Chrome() cls.driver.implicitly_wait(5) cls.login_page = LoginPage(cls.driver) @classmethod def tearDownClass(cls): cls.driver.quit() def data_provider(self): return [ ('validUser1', 'validPass1', True), ('invalidUser', 'invalidPass', False), ('validUser2', 'wrongPass', False) ] def test_login_with_multiple_credentials(self): for username, password, is_valid in self.data_provider(): with self.subTest(username=username, password=password): self.login_page.load() self.login_page.login(username, password) if is_valid: WebDriverWait(self.driver, 10).until( EC.url_to_be('https://example.com/dashboard') ) current_url = self.driver.current_url self.assertEqual(current_url, 'https://example.com/dashboard', f'Expected dashboard URL for valid user {username}') else: self.assertTrue(self.login_page.is_error_displayed(), f'Error message should be displayed for invalid user {username}')
This test script uses Selenium with Python's unittest framework.
We define a LoginPage class as a Page Object to handle page actions and locators. This keeps code clean and reusable.
The data_provider method returns multiple sets of username, password, and expected validity.
The test method test_login_with_multiple_credentials loops over these data sets using subTest for clear reporting.
For valid credentials, it waits until the URL changes to the dashboard and asserts it matches.
For invalid credentials, it checks if the error message is visible.
Explicit waits ensure the test waits for elements or URL changes properly, avoiding flaky tests.
Setup and teardown methods open and close the browser once for all tests.
Now add data-driven testing with 3 different inputs using unittest's subTest and parameterize the test method.