Skip to content

Pytest Playbook — Config Template

Production-ready pyproject.toml baseline for Python projects.

Template

[tool.pytest.ini_options]
testpaths = ["tests"]                          # where pytest looks for tests
python_files = ["test_*.py", "*_test.py"]      # file discovery patterns
addopts = "-ra -q --strict-markers --strict-config --maxfail=1"
markers = [
  "unit: fast isolated tests",
  "integration: tests with DB or external systems",
  "slow: long-running tests",
]
filterwarnings = ["error"]                     # treat warnings as errors
xfail_strict = true                            # xfail tests that pass unexpectedly become failures
asyncio_mode = "auto"                          # skip @pytest.mark.asyncio marker

[tool.coverage.run]
source = ["src"]
branch = true                                  # measure branch coverage

[tool.coverage.report]
show_missing = true
fail_under = 100                               # enforce 100% coverage
exclude_lines = [
  "if TYPE_CHECKING:",                         # type-only imports
  "if __name__ == .__main__.:",                # script guards
]

Why These Defaults

Flag Reason
--strict-markers Rejects unregistered markers — catches typos
--strict-config Fails on unknown config keys — prevents silent misconfiguration
--maxfail=1 Stops early for faster local feedback
-ra Shows summary of all non-passed tests
-q Quiet output — less noise
filterwarnings = ["error"] Catches deprecation warnings before they become errors
xfail_strict = true xfail tests that unexpectedly pass become failures
fail_under = 100 Prevents coverage regression

Local vs CI

# local: fast feedback loop
pytest -x --lf -q

# CI: full quality gate
pytest -n auto --cov=src --cov-report=term-missing --cov-fail-under=100

Marker Strategy

Marker When to run
unit Every PR check
integration Dedicated CI job with services
slow Nightly
pytest -m "unit and not slow"
pytest -m integration
uv add --dev pytest pytest-cov pytest-xdist pytest-asyncio pytest-mock pytest-randomly

Config Review Checklist

  • All custom markers registered and actively used.
  • Coverage threshold matches team policy.
  • Async mode configured if async code exists.
  • No legacy setup.cfg / pytest.ini conflicts.
  • filterwarnings set to ["error"].