0
0
PyTesttesting~15 mins

Why advanced patterns handle real-world complexity in PyTest - Automation Benefits in Action

Choose your learning style9 modes available
Automate login and profile update with complex user flows
Preconditions (2)
Step 1: Enter 'testuser' in the username field
Step 2: Enter 'Test@1234' in the password field
Step 3: Click the login button
Step 4: Wait until the dashboard page loads
Step 5: Navigate to the profile settings page
Step 6: Update the user's display name to 'Test User Updated'
Step 7: Save the changes
Step 8: Verify that a success message 'Profile updated successfully' is displayed
Step 9: Log out from the application
Step 10: Verify that the login page is displayed again
✅ Expected Result: User logs in successfully, updates profile display name, sees success message, and logs out returning to login page
Automation Requirements - pytest with Selenium WebDriver
Assertions Needed:
Verify dashboard page URL after login
Verify profile update success message is visible
Verify login page URL after logout
Best Practices:
Use Page Object Model to separate page interactions
Use explicit waits to handle dynamic page loading
Use pytest fixtures for setup and teardown
Use clear and reusable locators
Use assertions with meaningful messages
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.username_input = (By.ID, 'username')
        self.password_input = (By.ID, 'password')
        self.login_button = (By.ID, 'loginBtn')

    def login(self, username, password):
        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()

class DashboardPage:
    def __init__(self, driver):
        self.driver = driver
        self.profile_link = (By.ID, 'profileLink')

    def wait_for_dashboard(self):
        WebDriverWait(self.driver, 10).until(
            EC.url_contains('/dashboard')
        )

    def go_to_profile(self):
        self.driver.find_element(*self.profile_link).click()

class ProfilePage:
    def __init__(self, driver):
        self.driver = driver
        self.display_name_input = (By.ID, 'displayName')
        self.save_button = (By.ID, 'saveProfile')
        self.success_message = (By.ID, 'successMsg')

    def update_display_name(self, new_name):
        self.driver.find_element(*self.display_name_input).clear()
        self.driver.find_element(*self.display_name_input).send_keys(new_name)
        self.driver.find_element(*self.save_button).click()

    def wait_for_success_message(self):
        WebDriverWait(self.driver, 10).until(
            EC.visibility_of_element_located(self.success_message)
        )

    def get_success_message_text(self):
        return self.driver.find_element(*self.success_message).text

class BasePage:
    def __init__(self, driver):
        self.driver = driver
        self.logout_button = (By.ID, 'logoutBtn')

    def logout(self):
        self.driver.find_element(*self.logout_button).click()

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

@pytest.mark.usefixtures('driver')
def test_login_update_profile_logout(driver):
    driver.get('https://example.com/login')

    login_page = LoginPage(driver)
    login_page.login('testuser', 'Test@1234')

    dashboard_page = DashboardPage(driver)
    dashboard_page.wait_for_dashboard()
    assert '/dashboard' in driver.current_url, 'Dashboard URL not loaded after login'

    dashboard_page.go_to_profile()

    profile_page = ProfilePage(driver)
    profile_page.update_display_name('Test User Updated')
    profile_page.wait_for_success_message()
    success_text = profile_page.get_success_message_text()
    assert success_text == 'Profile updated successfully', 'Success message not shown or incorrect'

    base_page = BasePage(driver)
    base_page.logout()

    WebDriverWait(driver, 10).until(
        EC.url_contains('/login')
    )
    assert '/login' in driver.current_url, 'Login page not shown after logout'

This test script uses the Page Object Model to organize code for each page: LoginPage, DashboardPage, ProfilePage, and BasePage for logout. This keeps locators and actions in one place, making maintenance easier.

We use explicit waits (WebDriverWait) to wait for pages to load or messages to appear, which handles real-world delays and dynamic content.

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

Assertions check the URL after login and logout, and verify the success message text after profile update, ensuring the test validates expected outcomes clearly.

This approach handles real-world complexity by separating concerns, waiting properly, and making tests readable and maintainable.

Common Mistakes - 3 Pitfalls
Using hardcoded sleep (time.sleep) instead of explicit waits
Mixing locators and test logic in the test function
Not verifying important outcomes like URL changes or success messages
Bonus Challenge

Now add data-driven testing with 3 different user credentials and display names

Show Hint