Configuring pytest in pyproject.toml

pytest · Practical · 10 min

Shared configuration means local runs and CI use identical options, paths and rules.

pytest reads configuration from the first of pytest.toml, pytest.ini, pyproject.toml, tox.ini or setup.cfg that has a pytest section, searching from the common ancestor of the given paths upward. Its directory becomes the rootdir, used for node ids and the cache.

In pyproject.toml, pytest 9 reads a native [tool.pytest] table with real TOML types; the older [tool.pytest.ini_options] table with ini-style values still works and is what you'll see in most existing projects.

Options worth setting in every project:

  • testpaths = ["tests"]: where to look when you run bare pytest, which speeds up collection.
  • addopts: default flags, e.g. ["-ra", "--strict-markers"].
  • markers: register custom markers with descriptions.
  • strict = true (pytest 9): turns on strict config, strict markers, strict xfail and strict parametrize ids together.
  • filterwarnings = ["error"]: turn warnings into errors, with exceptions for noisy third-party ones.
  • minversion / required_plugins to fail fast in a misconfigured environment.
  • pythonpath = ["src"] if you don't install the package.

Any option can be overridden for a single run with -o name=value. pytest --help lists every configuration key, including those added by plugins, at the bottom.

Example

# pyproject.toml  (pytest 9 native TOML table)
[tool.pytest]
minversion = "9.0"
testpaths = ["tests"]
addopts = ["-ra"]
strict = true
markers = [
    "slow: long-running tests (deselect with -m 'not slow')",
    "integration: needs external services",
]
filterwarnings = [
    "error",
    "ignore::DeprecationWarning:somelib.*",
]

# Older equivalent, still supported:
# [tool.pytest.ini_options]
# testpaths = ["tests"]
# addopts = "-ra --strict-markers"

Remember

  • Configuration lives in pytest.toml, pytest.ini or pyproject.toml
  • pytest 9 supports a native [tool.pytest] table; ini_options still works
  • Set testpaths, addopts, markers and strictness
  • filterwarnings = ['error'] catches deprecations early

Watch out for

  • Having both pytest.ini and a pyproject section and editing the one pytest ignores.

Check yourself

  1. What does testpaths = ['tests'] change?

Sign in to answer, see the explanations, and get this lesson back as a quick review later.

Official docs: docs.pytest.org/en/stable/reference/customize.html