Bird
Raised Fist0
PyTesttesting~15 mins

Custom markers in PyTest - Deep Dive

Choose your learning style10 modes available
Overview - Custom markers
What is it?
Custom markers in pytest are labels you add to tests to organize, select, or skip them based on specific conditions. They let you tag tests with meaningful names like 'slow' or 'database' so you can run or ignore groups of tests easily. This helps manage large test suites by controlling which tests run and when. Markers are simple to add and use in pytest configuration and command line.
Why it matters
Without custom markers, running or skipping specific tests in big projects would be hard and slow. You might waste time running all tests when only some are relevant, or miss running important groups. Custom markers solve this by letting you quickly pick tests by category, improving testing speed and focus. This saves developers time and helps catch bugs faster.
Where it fits
Before learning custom markers, you should know basic pytest test writing and running tests. After this, you can learn about pytest fixtures and parameterization to write more flexible tests. Later, you might explore pytest hooks and plugins to customize test behavior even more.
Mental Model
Core Idea
Custom markers are like colored stickers you put on tests to group and control which ones run or skip.
Think of it like...
Imagine you have a big box of photos and you put colored stickers on some to mark 'family', 'vacation', or 'work'. Later, you can quickly find or ignore photos by sticker color. Custom markers do the same for tests.
┌───────────────┐
│   Test Suite  │
├───────────────┤
│ Test A [slow] │
│ Test B [db]   │
│ Test C [fast] │
│ Test D [slow] │
└───────────────┘

Command: pytest -m slow
Runs only tests with [slow] marker.
Build-Up - 6 Steps
1
FoundationWhat are pytest markers
🤔
Concept: Markers are labels you add to tests to identify or group them.
In pytest, you add a marker by placing @pytest.mark.name above a test function. For example: import pytest @pytest.mark.slow def test_example(): assert 1 + 1 == 2 This marks the test as 'slow'.
Result
The test is now tagged with 'slow' and can be selected or skipped using this label.
Understanding markers as simple labels helps you organize tests without changing test code logic.
2
FoundationRunning tests by marker
🤔
Concept: You can run only tests with a specific marker using pytest command options.
To run tests marked 'slow', use: pytest -m slow This runs only tests tagged with @pytest.mark.slow. Other tests are skipped.
Result
Only tests with the 'slow' marker run, speeding up test runs when you want to focus on certain tests.
Knowing how to run tests by marker lets you control test execution efficiently.
3
IntermediateDefining custom markers in pytest.ini
🤔Before reading on: do you think you can use any marker name without configuration? Commit to your answer.
Concept: Pytest requires you to declare custom markers in a config file to avoid warnings and document them.
Create a pytest.ini file with: [pytest] markers = slow: marks tests as slow to run db: marks tests that use the database This tells pytest about your custom markers.
Result
Pytest recognizes your markers without warnings and you can document their purpose.
Declaring markers prevents confusion and helps teams understand test categories.
4
IntermediateSkipping tests conditionally with markers
🤔Before reading on: can markers automatically skip tests without extra code? Commit to your answer.
Concept: Markers can be combined with pytest hooks or conditions to skip tests automatically.
You can skip tests with a marker using pytest's skipif marker: import sys import pytest @pytest.mark.skipif(sys.platform == 'win32', reason='No Windows support') def test_not_on_windows(): assert True This skips the test on Windows.
Result
Tests run only on allowed conditions, avoiding failures on unsupported platforms.
Markers can control test execution dynamically, not just label tests.
5
AdvancedUsing markers for test selection in CI pipelines
🤔Before reading on: do you think CI systems can use markers to run only some tests? Commit to your answer.
Concept: Markers help CI tools run targeted tests, saving time and resources.
In CI config, you can run: pytest -m 'not slow' to skip slow tests during quick checks, or pytest -m db to run only database tests when testing database changes.
Result
CI pipelines run faster and more relevant tests, improving feedback speed.
Markers integrate testing with development workflows for efficiency.
6
ExpertCreating custom marker plugins for advanced control
🤔Before reading on: can you extend pytest to add new marker behaviors? Commit to your answer.
Concept: You can write pytest plugins that add new marker logic or enforce marker rules.
A plugin can check marker usage or add new command line options. For example, a plugin might fail tests missing required markers or add a marker that runs tests only on certain environments.
Result
You gain fine-grained control over test selection and enforcement beyond basic markers.
Extending pytest with plugins leverages markers for powerful custom workflows.
Under the Hood
Pytest collects tests and attaches marker metadata to each test function object. When running tests, pytest filters tests based on marker expressions given in the command line. Markers are stored internally as attributes and checked during test collection and execution phases. The pytest.ini file registers markers to avoid warnings and provide descriptions. Skip conditions use marker metadata combined with runtime checks.
Why designed this way?
Markers were designed to be lightweight labels that don't change test code logic but allow flexible test grouping and selection. Registering markers in config prevents typos and documents usage. The design balances simplicity with powerful filtering, enabling both manual and automated test control without complex code changes.
┌───────────────┐
│ Test Functions│
│ + Marker Attr │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Test Collector│
│ Filters by    │
│ marker args   │
└──────┬────────┘
       │
       ▼
┌───────────────┐
│ Test Runner   │
│ Executes only │
│ selected tests│
└───────────────┘
Myth Busters - 4 Common Misconceptions
Quick: Can you use any marker name in pytest without declaring it? Commit yes or no.
Common Belief:You can use any marker name freely without configuration.
Tap to reveal reality
Reality:Pytest warns if you use markers not declared in pytest.ini or other config files.
Why it matters:Ignoring this causes noisy warnings and confusion about marker usage in teams.
Quick: Do markers change test logic or results? Commit yes or no.
Common Belief:Markers modify how tests run internally and can change test outcomes.
Tap to reveal reality
Reality:Markers only label tests; they don't change test code or results unless combined with skip or other logic.
Why it matters:Misunderstanding this leads to expecting markers to fix test bugs or change behavior without code changes.
Quick: Does pytest run all tests by default regardless of markers? Commit yes or no.
Common Belief:Markers restrict tests by default, so only marked tests run.
Tap to reveal reality
Reality:By default, pytest runs all tests unless you specify marker filters on the command line.
Why it matters:Thinking markers limit tests by default can cause missed tests or confusion about test coverage.
Quick: Can markers automatically skip tests without extra code? Commit yes or no.
Common Belief:Markers alone can skip tests automatically without any additional code or conditions.
Tap to reveal reality
Reality:Markers label tests; skipping requires combining markers with skipif or custom hooks.
Why it matters:Expecting automatic skipping leads to tests running unexpectedly and wasted test time.
Expert Zone
1
Markers can be combined with pytest hooks to implement complex test selection logic beyond simple labels.
2
Using marker expressions with logical operators (and, or, not) allows precise test filtering in large suites.
3
Markers can be used to enforce test policies by failing tests missing required markers via custom plugins.
When NOT to use
Avoid using markers for test data variation; use fixtures or parameterization instead. Also, don't rely solely on markers for test dependencies; use pytest dependency plugins or fixtures for that.
Production Patterns
In production, teams use markers to separate slow, integration, or flaky tests and run them selectively in CI. Markers also help run tests by feature area or environment, improving test feedback and resource use.
Connections
Test Fixtures
Complementary concepts in pytest
Markers group tests, while fixtures provide setup data; together they create flexible, maintainable tests.
Feature Flags in Software Development
Similar pattern of conditional enabling
Both markers and feature flags control what runs or is visible based on conditions, improving control and flexibility.
Library Classification in a Library System
Same pattern of labeling for organization
Just like books are labeled by genre or topic for easy finding, tests are marked to organize and select them efficiently.
Common Pitfalls
#1Using markers without declaring them in pytest.ini causes warnings.
Wrong approach:[pytest] # no markers declared # test file import pytest @pytest.mark.slow def test_func(): assert True
Correct approach:[pytest] markers = slow: marks tests as slow # test file import pytest @pytest.mark.slow def test_func(): assert True
Root cause:Not declaring markers leads pytest to warn about unknown markers.
#2Expecting markers alone to skip tests without skipif or hooks.
Wrong approach:import pytest @pytest.mark.slow def test_func(): assert True # run pytest normally, expecting skip
Correct approach:import pytest @pytest.mark.skipif(True, reason='skip always') def test_func(): assert True
Root cause:Markers label tests but skipping requires explicit skip conditions.
#3Running pytest without -m runs all tests ignoring markers.
Wrong approach:pytest # expects only 'slow' tests to run
Correct approach:pytest -m slow # runs only tests marked 'slow'
Root cause:Markers filter tests only when specified in command line.
Key Takeaways
Custom markers in pytest are labels that help organize and control test execution.
Markers must be declared in pytest.ini to avoid warnings and document their use.
You run tests by marker using the -m option, which filters tests to run or skip.
Markers alone do not change test logic or skip tests; they must be combined with conditions.
Advanced use includes combining markers with plugins and CI pipelines for efficient testing.

Practice

(1/5)
1. What is the main purpose of using custom markers in pytest?
easy
A. To generate test data automatically
B. To change the Python interpreter version
C. To automatically fix test failures
D. To label tests for grouping and selective running

Solution

  1. Step 1: Understand what custom markers do

    Custom markers in pytest are used to tag tests with labels for easier management.
  2. Step 2: Identify the purpose of these labels

    These labels help run specific groups of tests selectively using the marker name.
  3. Final Answer:

    To label tests for grouping and selective running -> Option D
  4. Quick Check:

    Custom markers = test grouping [OK]
Hint: Markers tag tests to run groups easily [OK]
Common Mistakes:
  • Thinking markers change Python version
  • Assuming markers fix test errors automatically
  • Confusing markers with test data generation
2. Which of the following is the correct syntax to mark a test with a custom marker named slow?
easy
A. @pytest.mark.slow\ndef test_example(): pass
B. @pytest.slow.mark\ndef test_example(): pass
C. @pytest.mark[slow]\ndef test_example(): pass
D. @pytest.mark('slow')\ndef test_example(): pass

Solution

  1. Step 1: Recall pytest marker syntax

    Custom markers use dot notation: @pytest.mark.markername before the test function.
  2. Step 2: Match the correct syntax

    @pytest.mark.slow is the correct way to apply the 'slow' marker.
  3. Final Answer:

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

    Marker syntax = @pytest.mark.name [OK]
Hint: Use dot notation: @pytest.mark.name [OK]
Common Mistakes:
  • Using parentheses instead of dot notation
  • Using square brackets instead of dot notation
  • Placing marker after function name
3. Given the following test file, what will be the output when running pytest -m slow?
import pytest

@pytest.mark.slow
def test_a():
    assert True

def test_b():
    assert True

@pytest.mark.slow
def test_c():
    assert False
medium
A. Runs all tests; test_c fails
B. Runs only test_b; all pass
C. Runs test_a and test_c; test_c fails, test_a passes
D. Runs test_a and test_b; all pass

Solution

  1. Step 1: Understand what pytest -m slow does

    This command runs only tests marked with the 'slow' marker.
  2. Step 2: Identify marked tests in the code

    test_a and test_c have @pytest.mark.slow, so only these run.
  3. Step 3: Check test results

    test_a passes (assert True), test_c fails (assert False).
  4. Final Answer:

    Runs test_a and test_c; test_c fails, test_a passes -> Option C
  5. Quick Check:

    pytest -m slow runs marked tests only [OK]
Hint: -m runs only tests with that marker [OK]
Common Mistakes:
  • Assuming all tests run with -m option
  • Ignoring test failures in marked tests
  • Running unmarked tests by mistake
4. What is wrong with this pytest marker usage?
import pytest

@pytest.mark.slow()
def test_example():
    assert True
medium
A. Markers should not have parentheses unless parameters are used
B. Marker name must be uppercase
C. The test function must have parameters
D. pytest.mark cannot be used on test functions

Solution

  1. Step 1: Check marker syntax

    Markers without parameters should not have parentheses; @pytest.mark.slow() is incorrect.
  2. Step 2: Correct usage

    Use @pytest.mark.slow without parentheses for simple markers.
  3. Final Answer:

    Markers should not have parentheses unless parameters are used -> Option A
  4. Quick Check:

    Use parentheses only with marker args [OK]
Hint: No parentheses for simple markers [OK]
Common Mistakes:
  • Adding empty parentheses to markers
  • Using uppercase marker names incorrectly
  • Thinking markers require function parameters
5. You want to run tests marked as database but exclude those also marked as slow. Which pytest command achieves this?
hard
A. pytest -m "database or slow"
B. pytest -m "database and not slow"
C. pytest -m "not database and slow"
D. pytest -m "database and slow"

Solution

  1. Step 1: Understand marker expressions

    pytest supports boolean expressions with markers: and, or, not.
  2. Step 2: Formulate the correct expression

    To run tests marked 'database' but exclude 'slow', use "database and not slow".
  3. Final Answer:

    pytest -m "database and not slow" -> Option B
  4. Quick Check:

    Use boolean logic in -m to include/exclude markers [OK]
Hint: Use boolean logic: -m "marker and not other" [OK]
Common Mistakes:
  • Using 'or' instead of 'and not' to exclude
  • Misplacing 'not' before the first marker
  • Combining markers without quotes
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