0
0
PyTesttesting~15 mins

Why organized tests scale with projects in PyTest - Automation Benefits in Action

Choose your learning style9 modes available
Verify user login functionality with organized test structure
Preconditions (2)
Step 1: Open the login page at http://localhost:5000/login
Step 2: Enter 'testuser' in the username field
Step 3: Enter 'Test@1234' in the password field
Step 4: Click the login button
Step 5: Verify that the user is redirected to the dashboard page at /dashboard
Step 6: Verify that the dashboard page contains the text 'Welcome, testuser!'
✅ Expected Result: User successfully logs in and sees the dashboard welcome message
Automation Requirements - pytest with Selenium WebDriver
Assertions Needed:
Assert current URL is http://localhost:5000/dashboard
Assert page contains text 'Welcome, testuser!'
Best Practices:
Use Page Object Model to separate page interactions
Use explicit waits to handle dynamic page loading
Organize tests in folders and modules by feature
Use pytest fixtures for setup and teardown
Automated Solution
PyTest
import pytest
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 = "http://localhost:5000/login"
        self.username_input = (By.ID, "username")
        self.password_input = (By.ID, "password")
        self.login_button = (By.ID, "login-btn")

    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).send_keys(username)
        self.driver.find_element(*self.password_input).send_keys(password)
        self.driver.find_element(*self.login_button).click()

class DashboardPage:
    def __init__(self, driver):
        self.driver = driver
        self.welcome_text_locator = (By.XPATH, "//h1[contains(text(), 'Welcome,')]")

    def is_loaded(self):
        return WebDriverWait(self.driver, 10).until(
            EC.url_contains("/dashboard")
        )

    def get_welcome_text(self):
        return self.driver.find_element(*self.welcome_text_locator).text

@pytest.fixture
def driver():
    driver = webdriver.Chrome()
    driver.implicitly_wait(5)
    yield driver
    driver.quit()

@pytest.mark.usefixtures("driver")
def test_user_can_login(driver):
    login_page = LoginPage(driver)
    dashboard_page = DashboardPage(driver)

    login_page.load()
    login_page.login("testuser", "Test@1234")

    assert dashboard_page.is_loaded(), "Dashboard page did not load"
    welcome_text = dashboard_page.get_welcome_text()
    assert welcome_text == "Welcome, testuser!", f"Unexpected welcome text: {welcome_text}"

This test script uses pytest and Selenium WebDriver to automate the login test.

We use the Page Object Model to keep page details separate from test logic. LoginPage handles login page actions, and DashboardPage handles dashboard checks.

Explicit waits ensure elements are ready before interacting, avoiding flaky tests.

The driver fixture sets up and tears down the browser cleanly.

The test test_user_can_login loads the login page, performs login, then asserts the dashboard URL and welcome message.

This organized structure helps tests stay clear and easy to maintain as the project grows.

Common Mistakes - 4 Pitfalls
{'mistake': 'Hardcoding waits like time.sleep instead of using explicit waits', 'why_bad': 'It makes tests slow and flaky because the wait time may be too short or too long.', 'correct_approach': "Use Selenium's explicit waits (WebDriverWait) to wait only as long as needed for elements."}
Mixing test logic and page interaction code in the same function
Not quitting the browser after tests
Using brittle locators like absolute XPaths
Bonus Challenge

Now add data-driven testing with 3 different username and password combinations

Show Hint