Cribsheet — Pytest

Notes to self on using pytest.

TODO: Combine this with the “Starter” post.

Run Specific Tests

pytest test_file.py
pytest test_file.py::test_function

Options

  • -s — Show content printed to stdout
  • --log-cli-level — Show logging output for specified level
  • --disable-warnings — Suppress warning messages
  • -v — Verbose output
  • -x — Stop after the first failure
  • --maxfail — Stop after specific number of failures
  • --lf / --last-failed — Only rerun the tests that failed previously
  • --ff / --failed-first — Run failed tests first
  • --durations — Show specified number of slowest tests

Fixtures

https://patrickm.de/pytest-fixtures-how-to-use-organize-them-in-your-test-architecture/

Plugins

pytest-cov

  • --cov= — Path of folder. Set to . for current folder.
  • --cov-report=term — Report in terminal.
  • --cov-report=term-missing — Report in terminal with lines not covered.
  • --cov-report=html — Report as HTML.

You can append :skip-covered to the required report and files with 100% coverage will be ignored.

pytest-timeout

  • --timeout — Change the timeout (set to 0 to disable)

pytest-socket

  • --allow-hosts — List of allowed IP addresses

«««< Updated upstream

Flags:

-x: stop a first failure.
--pdb: start the Python debugger on failure.
-k <filter>: only discover tests that match the filter.
--ff: start with tests that failed in the previous run.
--nf: start with new files.
--sw: start from where it stopped the previous run.
--no-header / --no-summary: remove the big blobs of texts in the output.
--verbosity=x: from 0 to 3 levels of output granularity.
- s to avoid stdout capture
--log-cli-level

Project structure (UPDATE FILE NAMES!):

less_basic_project
├── my_awesome_package
│   ├── __init__.py
│   └── the_code_to_test.py
├── pyproject.toml
└── tests
    └── the_tests.py

What to put in pyproject.toml:

[tool.pytest.ini_options] # mandatory section name
addopts = "-s" # force a command line option
testpaths = [ # what directories contain tests
    "tests",
]
pythonpath = [ # what to add to the python path
    "."
]

FAQ

Package not found

This can often be fixed by placing an empty __init__.py into the tests/ directory.

Logging & Standard Output

https://adamj.eu/tech/2025/08/29/python-unittest-capture-stdout-stderr/ for stdout

Use the caplog fixture for logging (https://docs.pytest.org/en/stable/how-to/logging.html). NB for Mypy: Type is pytest.LogCaptureFixture.

By default standard output is captured. This can be disabled globally via the -s option. However, it can also be done locally via a fixture or marker.

THESE CODE SAMPLES WERE COPIED!

def test_foo(capsys):
    print('captured')
    with capsys.disabled():
         print('directly to stdout, regardless of the "-s" flag')
    print('captured again')
@pytest.mark.capture_disabled
def test_foo():
    print('directly to stdout, regardless of the "-s" flag') 

Stashed changes