Skip to main content

pytest-route-coverage

A pytest plugin that tracks HTTP requests made during your test suite and tells you which routes were tested and which weren't.

Supported Frameworks

Only Django is currently supported. You can open an issue (or a PR) if you'd like support for other frameworks.

Installation

pip install pytest-route-coverage

Usage

Run your tests with the --route-coverage flag:

pytest --route-coverage

This writes a .route-coverage JSON file to your project root. To see the report:

route-coverage show

Example output:

============================================================
Routes hit during tests
============================================================
  GET     /fakes/  [200]x1

  Total requests: 1
============================================================
Route coverage by test
============================================================
  GET     /fakes/
          - tests/test_views.py::test_list_fakes

============================================================
Untested routes
============================================================
  POST    /fakes/  (app/views.py)

  Untested: 1 route(s)

By default, all untested routes are shown. Pass --tested-files-only to limit the report to source files that had at least one route tested - useful when running a subset of tests:

route-coverage show --tested-files-only

How it works

The plugin works by injecting a middleware into Django's middleware stack at the start of the test session. This middleware records every request that passes through it — method, path, status code, and which test triggered it.

This means it only captures requests that go through Django's full request/response cycle, i.e., tests that use django.test.Client, DRF's APIClient, or similar. If a test calls a view function directly, that request won't be recorded and the route will show up as untested. This is intentional: a direct function call doesn't exercise routing, middleware, authentication, or any of the other layers a real request would hit.

At the end of the session, the plugin walks Django's URL resolver to build a list of all registered DRF endpoints and writes everything to .route-coverage. The CLI then cross-references the request log against registered routes to find the gaps.

pytest-xdist support

Works out of the box with pytest-xdist. Request logs from all workers are collected on the controller node and merged into a single results file.

pytest --route-coverage -n auto

Parallel and append modes

For CI pipelines that split tests across multiple jobs:

# Each job writes its own file
pytest --route-coverage --route-coverage-parallel

# After all jobs finish, combine them
route-coverage combine

# Or accumulate results incrementally
pytest --route-coverage --route-coverage-append

--route-coverage-parallel writes to .route-coverage.{hostname}.{pid}.{hex} instead of the base file. route-coverage combine merges all suffix files into .route-coverage and cleans up the originals (pass --keep to preserve them).

--route-coverage-append merges new results into an existing .route-coverage file. These two flags are mutually exclusive.

Development

uv sync --group dev
uv run pytest

Running tests

Tests cover Django LTS and latest versions: 4.2, 5.2, and 6.0 (with and without xdist):

uv run tox

License

Apache-2.0

Metadata

Release files for pytest-route-coverage 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pytest-route-coverage 1.0.0
File Size Uploaded
pytest_route_coverage-1.0.0.tar.gz 7.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pytest-route-coverage 1.0.0
File Interpreter ABI Platform
pytest_route_coverage-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 17.9 kB

Release files / pytest_route_coverage-1.0.0.tar.gz

Download URL pytest_route_coverage-1.0.0.tar.gz
Size 7.6 kB
Tags Source
SHA-256 checksum
How to use checksums
05b97325f051ebe59405c0cba4301c0a5ea673b8d67dbd550583be8ee1006041
BLAKE2b-256 checksum
How to use checksums
2bae5a87cb36c5481be2d711a8aa20d82210cac0fa0d88e76fb9cdb1d9de39e2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / pytest_route_coverage-1.0.0-py3-none-any.whl

Download URL pytest_route_coverage-1.0.0-py3-none-any.whl
Size 10.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
6f54ee7bb2a6692054147f053f5defffdf55e95f4334b2d66c378a6c3973c316
BLAKE2b-256 checksum
How to use checksums
e79aafebe0b76f96ff4b45624416e155655cecf8b78cf254caab575a2c091b55
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.11.2 {"installer":{"name":"uv","version":"0.11.2","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"macOS","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page