0
0
PyTesttesting~15 mins

Custom markers in PyTest - Deep Dive

Choose your learning style9 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.