Bird
Raised Fist0
PyTesttesting~15 mins

Single responsibility per test in PyTest - Build an Automation Script

Choose your learning style10 modes available

Start learning this pattern below

Jump into concepts and practice - no test required

or
Recommended
Test this pattern10 questions across easy, medium, and hard to know if this pattern is strong
Verify login page functionalities with single responsibility tests
Preconditions (2)
Step 1: Open the login page
Step 2: Verify the page title is 'Login Page'
Step 3: Enter a valid username 'user1' in the username field
Step 4: Enter a valid password 'Password123' in the password field
Step 5: Click the login button
Step 6: Verify the user is redirected to the dashboard page
Step 7: Open the login page again
Step 8: Verify the username field is empty
Step 9: Verify the password field is empty
Step 10: Verify the login button is disabled when fields are empty
✅ Expected Result: Each test verifies only one functionality: page title, successful login, empty fields on load, and login button disabled state. All tests pass independently.
Automation Requirements - pytest
Assertions Needed:
Page title equals 'Login Page'
After login, URL contains '/dashboard'
Username and password fields are empty on page load
Login button is disabled when username or password is empty
Best Practices:
Write one assertion per test to keep single responsibility
Use pytest fixtures for setup like opening the login page
Use clear and descriptive test function names
Avoid combining multiple checks in one test
Use explicit waits if needed for page load
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

@pytest.fixture
sdef driver():
    driver = webdriver.Chrome()
    driver.get('https://example.com/login')
    yield driver
    driver.quit()

@pytest.fixture
def wait(driver):
    return WebDriverWait(driver, 10)


def test_login_page_title(driver):
    assert driver.title == 'Login Page'


def test_successful_login_redirect(driver, wait):
    username_input = driver.find_element(By.ID, 'username')
    password_input = driver.find_element(By.ID, 'password')
    login_button = driver.find_element(By.ID, 'login-btn')

    username_input.send_keys('user1')
    password_input.send_keys('Password123')
    login_button.click()

    wait.until(EC.url_contains('/dashboard'))
    assert '/dashboard' in driver.current_url


@pytest.fixture
def open_login_page(driver):
    driver.get('https://example.com/login')


def test_username_field_empty_on_load(driver, open_login_page):
    username_input = driver.find_element(By.ID, 'username')
    assert username_input.get_attribute('value') == ''


def test_password_field_empty_on_load(driver, open_login_page):
    password_input = driver.find_element(By.ID, 'password')
    assert password_input.get_attribute('value') == ''


def test_login_button_disabled_when_fields_empty(driver, open_login_page):
    login_button = driver.find_element(By.ID, 'login-btn')
    assert not login_button.is_enabled()

This test suite uses pytest with Selenium WebDriver to automate the login page tests.

We use fixtures to open the browser and navigate to the login page before each test.

Each test checks only one thing: the page title, successful login redirect, empty username field, empty password field, and login button disabled state.

This keeps tests simple and focused, making failures easier to understand and fix.

Explicit waits ensure the page redirects before asserting the URL.

Common Mistakes - 3 Pitfalls
Combining multiple assertions in one test
Not resetting the page state between tests
Using implicit waits or no waits causing timing issues
Bonus Challenge

Now add data-driven testing with 3 different sets of valid usernames and passwords for the login test

Show Hint

Practice

(1/5)
1. What is the main reason to write a test with a single responsibility in pytest?
easy
A. To run all tests faster at once
B. To make the test easier to understand and fix when it fails
C. To combine many checks in one test for efficiency
D. To avoid writing multiple test functions

Solution

  1. Step 1: Understand test clarity

    Tests with one responsibility focus on one behavior, making it clear what failed.
  2. Step 2: Benefits of single responsibility

    This clarity helps developers quickly find and fix issues without confusion.
  3. Final Answer:

    To make the test easier to understand and fix when it fails -> Option B
  4. Quick Check:

    Single responsibility = clarity and easier fixes [OK]
Hint: One test, one check, easy to read and fix [OK]
Common Mistakes:
  • Trying to test many things in one test
  • Ignoring test readability
  • Using unclear test names
2. Which of the following pytest test function names best follows the single responsibility principle?
easy
A. test_user_login_and_profile_update
B. test_all_user_functions
C. test_user_login_with_valid_credentials
D. test_user_actions

Solution

  1. Step 1: Analyze test names for specificity

    Names should describe one clear behavior or feature being tested.
  2. Step 2: Compare options

    test_user_login_with_valid_credentials clearly states it tests login with valid credentials only, so it has a single responsibility.
  3. Final Answer:

    test_user_login_with_valid_credentials -> Option C
  4. Quick Check:

    Clear, specific test name = single responsibility [OK]
Hint: Pick the test name that describes one clear action [OK]
Common Mistakes:
  • Using vague or combined test names
  • Testing multiple features in one test
  • Ignoring descriptive naming
3. Given this pytest code, what will be the test result?
def test_example():
    x = 5
    assert x == 5
    assert x > 0
medium
A. Test passes because both assertions are true
B. Test fails because multiple assertions are not allowed
C. Test fails because x is not defined
D. Test passes but only the first assertion is checked

Solution

  1. Step 1: Check variable and assertions

    Variable x is set to 5, which satisfies both assertions: x == 5 and x > 0.
  2. Step 2: Understand pytest assertion behavior

    Pytest allows multiple assertions; all are checked unless one fails first. Here both pass.
  3. Final Answer:

    Test passes because both assertions are true -> Option A
  4. Quick Check:

    All assertions true = test passes [OK]
Hint: Check each assertion truth; all must pass for test pass [OK]
Common Mistakes:
  • Thinking multiple assertions cause failure
  • Assuming only first assertion runs
  • Confusing variable scope
4. Identify the problem in this pytest test function that violates single responsibility:
def test_user():
    assert login('user') == True
    assert update_profile('user', 'new info') == True
medium
A. The test has syntax errors
B. The test uses invalid function calls
C. The test misses setup code
D. The test checks two different features in one function

Solution

  1. Step 1: Review test actions

    The test checks login and profile update in the same function, two separate features.
  2. Step 2: Understand single responsibility principle

    Each test should check only one behavior to keep tests clear and focused.
  3. Final Answer:

    The test checks two different features in one function -> Option D
  4. Quick Check:

    Multiple features in one test = violation [OK]
Hint: One test, one feature; multiple features break single responsibility [OK]
Common Mistakes:
  • Ignoring multiple assertions as multiple responsibilities
  • Assuming syntax errors cause failure here
  • Confusing setup with test logic
5. You have a test that checks user registration, login, and logout all in one function. How should you refactor it to follow single responsibility in pytest?
hard
A. Split the test into three separate tests: one for registration, one for login, and one for logout
B. Keep all checks in one test but add comments to separate them
C. Remove login and logout checks and test only registration
D. Combine registration and login in one test, logout in another

Solution

  1. Step 1: Identify responsibilities in the test

    The test currently checks three different user actions: registration, login, and logout.
  2. Step 2: Apply single responsibility principle

    Each test should focus on one action to improve clarity and maintainability.
  3. Step 3: Refactor approach

    Splitting into three tests ensures each test checks only one feature clearly.
  4. Final Answer:

    Split the test into three separate tests: one for registration, one for login, and one for logout -> Option A
  5. Quick Check:

    One test per feature = better clarity and easier fixes [OK]
Hint: Split combined tests into single-feature tests [OK]
Common Mistakes:
  • Keeping multiple features in one test with comments
  • Removing features instead of splitting
  • Partially splitting tests inconsistently