Bird
Raised Fist0
Selenium Pythontesting~15 mins

Markers for categorization in Selenium Python - Build an Automation Script

Choose your learning style10 modes available
Verify login functionality with valid credentials using markers for categorization
Preconditions (2)
Step 1: Open the browser and navigate to https://example.com/login
Step 2: Enter 'validuser@example.com' in the email input field with id 'email'
Step 3: Enter 'ValidPass123!' in the password input field with id 'password'
Step 4: Click the login button with id 'loginBtn'
Step 5: Wait until the URL changes to https://example.com/dashboard
Step 6: Verify that the dashboard heading with tag h1 and text 'Welcome to your dashboard' is visible
✅ Expected Result: User is successfully logged in and redirected to the dashboard page with the welcome heading displayed
Automation Requirements - pytest with selenium
Assertions Needed:
Assert current URL is https://example.com/dashboard
Assert dashboard heading text is 'Welcome to your dashboard'
Best Practices:
Use pytest markers to categorize the test as 'smoke' and 'login'
Use explicit waits to wait for page elements and URL changes
Use Page Object Model to separate page interactions
Use clear and descriptive assertion messages
Automated Solution
Selenium Python
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.email_input = (By.ID, 'email')
        self.password_input = (By.ID, 'password')
        self.login_button = (By.ID, 'loginBtn')

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

    def login(self, email, password):
        self.driver.find_element(*self.email_input).send_keys(email)
        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.heading = (By.TAG_NAME, 'h1')

    def get_heading_text(self):
        return self.driver.find_element(*self.heading).text

@pytest.mark.smoke
@pytest.mark.login
def test_login_success():
    driver = webdriver.Chrome()
    wait = WebDriverWait(driver, 10)
    login_page = LoginPage(driver)
    dashboard_page = DashboardPage(driver)

    try:
        login_page.open()
        login_page.login('validuser@example.com', 'ValidPass123!')

        wait.until(EC.url_to_be('https://example.com/dashboard'))
        assert driver.current_url == 'https://example.com/dashboard', 'URL after login should be dashboard URL'

        wait.until(EC.visibility_of_element_located(dashboard_page.heading))
        heading_text = dashboard_page.get_heading_text()
        assert heading_text == 'Welcome to your dashboard', f'Expected heading text but got "{heading_text}"'
    finally:
        driver.quit()

This test uses pytest markers @pytest.mark.smoke and @pytest.mark.login to categorize it as a smoke test and login test. This helps to run specific groups of tests easily.

The Page Object Model separates page details from the test logic. LoginPage handles login page actions, and DashboardPage handles dashboard page elements.

We use explicit waits with WebDriverWait and expected_conditions to wait for the URL to change and the dashboard heading to appear. This avoids flaky tests caused by timing issues.

Assertions check the URL and heading text with clear messages to help understand failures.

The finally block ensures the browser closes even if the test fails.

Common Mistakes - 4 Pitfalls
Not using explicit waits and relying on time.sleep
Hardcoding locators inside the test function instead of using Page Object Model
Not using pytest markers for categorization
Not closing the browser after test execution
Bonus Challenge

Now add data-driven testing with 3 different sets of valid login credentials using pytest parametrize.

Show Hint

Practice

(1/5)
1. What is the main purpose of using markers in pytest with Selenium tests?
easy
A. To write test cases faster
B. To label and organize tests for selective running
C. To automatically fix test failures
D. To generate test reports

Solution

  1. Step 1: Understand what markers do

    Markers are used to label tests so you can group or select them easily.
  2. Step 2: Identify the main purpose

    This helps run only certain tests or skip some, improving test control.
  3. Final Answer:

    To label and organize tests for selective running -> Option B
  4. Quick Check:

    Markers = Organize tests [OK]
Hint: Markers help pick which tests to run or skip [OK]
Common Mistakes:
  • Thinking markers speed up writing tests
  • Believing markers fix test errors automatically
  • Confusing markers with report generation
2. Which is the correct way to add a marker named smoke to a test function in pytest?
easy
A. @pytest.mark.smoke\ndef test_example(): pass
B. @pytest.mark('smoke')\ndef test_example(): pass
C. @pytest.mark[smoke]\ndef test_example(): pass
D. @pytest.mark->smoke\ndef test_example(): pass

Solution

  1. Step 1: Recall pytest marker syntax

    Markers use dot notation: @pytest.mark.marker_name above the test.
  2. Step 2: Match syntax to options

    Only @pytest.mark.smoke\ndef test_example(): pass uses correct dot notation without extra symbols.
  3. Final Answer:

    @pytest.mark.smoke\ndef test_example(): pass -> Option A
  4. Quick Check:

    Marker syntax = dot notation [OK]
Hint: Use dot notation: @pytest.mark.marker_name [OK]
Common Mistakes:
  • Using parentheses instead of dot notation
  • Using brackets or arrows incorrectly
  • Missing the @ symbol before pytest.mark
3. Given this pytest code snippet, what tests will run if you execute pytest -m smoke?
@pytest.mark.smoke
def test_login(): pass

@pytest.mark.regression
def test_checkout(): pass

def test_search(): pass
medium
A. Only test_login
B. Only test_checkout
C. Both test_login and test_checkout
D. All three tests

Solution

  1. Step 1: Understand pytest -m option

    The -m option runs tests with the given marker only.
  2. Step 2: Identify tests with 'smoke' marker

    Only test_login has @pytest.mark.smoke.
  3. Final Answer:

    Only test_login -> Option A
  4. Quick Check:

    pytest -m smoke runs smoke tests only [OK]
Hint: -m runs tests with matching marker only [OK]
Common Mistakes:
  • Running all tests ignoring markers
  • Confusing marker names
  • Assuming unmarked tests run with any marker
4. You wrote this test with a marker but it does not run when you use pytest -m regression. What is the error?
@pytest.mark.regresion
def test_payment(): pass
medium
A. Test function name is incorrect
B. Missing @ symbol before pytest.mark
C. Marker name is misspelled
D. pytest -m cannot run marked tests

Solution

  1. Step 1: Check marker spelling

    The marker used is 'regresion' but command uses 'regression'.
  2. Step 2: Understand effect of misspelling

    pytest -m regression won't find tests marked 'regresion', so test is skipped.
  3. Final Answer:

    Marker name is misspelled -> Option C
  4. Quick Check:

    Marker spelling must match exactly [OK]
Hint: Check marker spelling matches command exactly [OK]
Common Mistakes:
  • Typos in marker names
  • Forgetting @ before pytest.mark
  • Assuming pytest runs all marked tests without -m
5. You want to run all tests except those marked slow. Which pytest command should you use?
hard
A. pytest -m slow
B. pytest --exclude slow
C. pytest --skip slow
D. pytest -m "not slow"

Solution

  1. Step 1: Understand pytest marker expressions

    To exclude tests with a marker, use -m "not marker_name" syntax.
  2. Step 2: Match command to requirement

    pytest -m "not slow" uses "not slow" to run all tests except those marked slow.
  3. Final Answer:

    pytest -m "not slow" -> Option D
  4. Quick Check:

    Use -m "not marker" to exclude tests [OK]
Hint: Use -m "not marker" to skip marked tests [OK]
Common Mistakes:
  • Using -m marker to run only those tests
  • Using unsupported --skip or --exclude options
  • Not quoting the expression with spaces
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