Bird
Raised Fist0
Selenium Pythontesting~15 mins

Parameterize with test data in Selenium Python - Build an Automation Script

Choose your learning style10 modes available
Login functionality with multiple user credentials
Preconditions (5)
Step 1: Open the login page URL.
Step 2: Enter the email address from the test data into the email input field with id 'email'.
Step 3: Enter the password from the test data into the password input field with id 'password'.
Step 4: Click the login button with id 'loginBtn'.
Step 5: Wait for the page to load and verify the URL is 'https://example.com/dashboard'.
Step 6: Log out to return to the login page before the next test data is used.
✅ Expected Result: For each set of credentials, the user successfully logs in and is redirected to the dashboard page.
Automation Requirements - Selenium with Python unittest
Assertions Needed:
Verify the current URL after login matches 'https://example.com/dashboard'.
Best Practices:
Use parameterization to run the same test with multiple sets of data.
Use explicit waits to wait for page elements or URL changes.
Use Page Object Model to separate page interactions from test logic.
Clean up after each test by logging out to reset state.
Automated Solution
Selenium Python
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.email_input = (By.ID, 'email')
        self.password_input = (By.ID, 'password')
        self.login_button = (By.ID, 'loginBtn')
        self.logout_button = (By.ID, 'logoutBtn')

    def open(self):
        self.driver.get('https://example.com/login')

    def login(self, email, password):
        WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.email_input)).clear()
        self.driver.find_element(*self.email_input).send_keys(email)
        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 logout(self):
        WebDriverWait(self.driver, 10).until(EC.element_to_be_clickable(self.logout_button)).click()

class TestLogin(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        cls.driver = webdriver.Chrome()
        cls.driver.maximize_window()
        cls.login_page = LoginPage(cls.driver)

    @classmethod
    def tearDownClass(cls):
        cls.driver.quit()

    def setUp(self):
        self.login_page.open()

    def test_login_with_multiple_credentials(self):
        test_data = [
            ('user1@example.com', 'Password1!'),
            ('user2@example.com', 'Password2!'),
            ('user3@example.com', 'Password3!')
        ]
        for email, password in test_data:
            with self.subTest(email=email):
                self.login_page.login(email, password)
                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'Login failed for {email}')
                self.login_page.logout()

if __name__ == '__main__':
    unittest.main()

This script uses the Selenium WebDriver with Python's unittest framework to automate login tests with multiple user credentials.

LoginPage class: Encapsulates the login page elements and actions. This follows the Page Object Model to keep code organized.

TestLogin class: Contains the test case. It opens the login page before each test and closes the browser after all tests.

Parameterization: The test_login_with_multiple_credentials method loops over a list of email/password pairs. Each pair is tested separately using subTest for clear reporting.

Assertions: After login, the test waits explicitly for the URL to change to the dashboard URL and asserts it matches exactly.

Cleanup: After each login, the test logs out to reset the state for the next iteration.

This approach ensures the test is maintainable, clear, and reliable.

Common Mistakes - 4 Pitfalls
Hardcoding test data inside the test method without parameterization
Using implicit waits or time.sleep instead of explicit waits
Not cleaning up after each test iteration (e.g., not logging out)
Using brittle locators like absolute XPaths
Bonus Challenge

Now add data-driven testing with 3 different inputs using unittest's parameterized library or pytest parametrize.

Show Hint

Practice

(1/5)
1. What is the main purpose of using @pytest.mark.parametrize in Selenium Python tests?
easy
A. To run tests in parallel threads
B. To skip tests that are not ready
C. To run the same test function multiple times with different input data
D. To generate HTML reports automatically

Solution

  1. Step 1: Understand the decorator's role

    @pytest.mark.parametrize allows running one test function multiple times with different sets of input data.
  2. Step 2: Compare with other options

    Skipping tests, running in parallel, or generating reports are different pytest features, not related to parameterization.
  3. Final Answer:

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

    Parameterize = run test with many inputs [OK]
Hint: Parameterize means run test repeatedly with different data [OK]
Common Mistakes:
  • Confusing parameterize with skipping tests
  • Thinking it runs tests in parallel
  • Assuming it generates reports
2. Which of the following is the correct syntax to parameterize a test function with two sets of inputs ("user1", "pass1") and ("user2", "pass2") in pytest?
easy
A. @pytest.parametrize('username', ['user1', 'user2'], 'password', ['pass1', 'pass2'])
B. @pytest.mark.parametrize('username, password', [('user1', 'pass1'), ('user2', 'pass2')])
C. @pytest.mark.parametrize(['username', 'password'], 'user1', 'pass1', 'user2', 'pass2')
D. @pytest.mark.parametrized('username', 'password', [('user1', 'pass1'), ('user2', 'pass2')])

Solution

  1. Step 1: Recall correct decorator syntax

    The correct syntax uses @pytest.mark.parametrize with a string of parameter names and a list of tuples for values.
  2. Step 2: Identify correct option

    @pytest.mark.parametrize('username, password', [('user1', 'pass1'), ('user2', 'pass2')]) matches the correct syntax exactly. Other options have wrong method names or argument formats.
  3. Final Answer:

    @pytest.mark.parametrize('username, password', [('user1', 'pass1'), ('user2', 'pass2')]) -> Option B
  4. Quick Check:

    Parametrize('params', [tuples]) = correct syntax [OK]
Hint: Use string param names and list of tuples for values [OK]
Common Mistakes:
  • Misspelling 'parametrize' as 'parametrized' or 'parametrize'
  • Passing parameters as separate lists instead of tuples
  • Using wrong decorator name
3. Given the following test code, what will be the output when running the test?
import pytest

@pytest.mark.parametrize('num, expected', [(1, 2), (3, 4)])
def test_increment(num, expected):
    assert num + 1 == expected
medium
A. First test fails, second test passes
B. Both tests fail
C. First test passes, second test fails
D. Both tests pass

Solution

  1. Step 1: Analyze each test case

    For (1, 2): 1 + 1 = 2, assertion passes. For (3, 4): 3 + 1 = 4, assertion passes.
  2. Step 2: Determine overall result

    Since both assertions pass, both tests pass successfully.
  3. Final Answer:

    Both tests pass -> Option D
  4. Quick Check:

    num+1 == expected for all inputs [OK]
Hint: Check each input pair separately for assertion [OK]
Common Mistakes:
  • Assuming one test fails without checking values
  • Confusing expected values with actual calculation
  • Ignoring that both inputs are tested
4. Identify the error in the following parameterized test code:
import pytest

@pytest.mark.parametrize('username, password')
def test_login(username, password):
    assert username != '' and password != ''
medium
A. Missing list of parameter values in @pytest.mark.parametrize decorator
B. Function parameters do not match decorator parameters
C. Assertion logic is incorrect
D. pytest module is not imported

Solution

  1. Step 1: Check decorator usage

    The decorator @pytest.mark.parametrize requires two arguments: parameter names and a list of values. Here, the list of values is missing.
  2. Step 2: Verify other parts

    Function parameters match decorator names, assertion logic is valid, and pytest is imported correctly.
  3. Final Answer:

    Missing list of parameter values in @pytest.mark.parametrize decorator -> Option A
  4. Quick Check:

    Parametrize needs names and values [OK]
Hint: Always provide parameter values list with parametrize [OK]
Common Mistakes:
  • Forgetting the list of test data tuples
  • Mismatching parameter names and function arguments
  • Incorrect assertion logic
5. You want to test a login form with multiple username and password pairs using Selenium and pytest. Which approach correctly applies parameterization and Selenium WebDriver usage together?
hard
A. Use @pytest.mark.parametrize to pass username and password, then inside the test open the browser, enter credentials, and assert login success
B. Write separate test functions for each username and password pair without parameterization
C. Use a loop inside a single test function to iterate over username and password pairs without parameterization
D. Use @pytest.mark.parametrize but open the browser only once outside the test function

Solution

  1. Step 1: Understand parameterization with Selenium

    Parameterization with @pytest.mark.parametrize allows running the test multiple times with different data, opening the browser fresh each time ensures test isolation.
  2. Step 2: Evaluate other options

    Writing separate tests duplicates code, looping inside one test loses pytest reporting benefits, and opening browser only once risks test interference.
  3. Final Answer:

    Use @pytest.mark.parametrize to pass username and password, then inside the test open the browser, enter credentials, and assert login success -> Option A
  4. Quick Check:

    Parametrize + fresh browser per test = best practice [OK]
Hint: Parametrize inputs and open browser inside test for isolation [OK]
Common Mistakes:
  • Opening browser once for all tests causing state issues
  • Not using parameterize and duplicating test code
  • Using loops inside tests instead of parameterize
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