pytest-strawberry
Pytest plugin for Strawberry GraphQL
pytest-strawberry measures which Strawberry GraphQL schema fields are reached
while your pytest suite runs. It reports schema field coverage independently of
Python source coverage.
Installation
pip install pytest-strawberry
Pytest loads the plugin automatically through its pytest11 entry point.
Field coverage
Enable coverage on the pytest command line:
pytest --strawberry-coverage
By default, the report covers fields with explicit Strawberry resolvers, runtime field extensions, or custom field resolution supplied by integrations such as Strawberry Django. It excludes fields handled only by Strawberry's ordinary attribute lookup:
============================= Strawberry coverage =============================
Subscriptions: excluded (requires graphql-core 3.3+); graphql-core 3.2.11
Schema b6016cac
┌───────────────────┬────────┬──────┬─────────┬───────────────────────┐
│ Python type │ Fields │ Miss │ Cover │ Missing fields │
├───────────────────┼────────┼──────┼─────────┼───────────────────────┤
│ QueryRoot [Query] │ 2 │ 0 │ 100.00% │ │
│ UserModel [User] │ 3 │ 1 │ 66.67% │ email_address [email] │
├───────────────────┼────────┼──────┼─────────┼───────────────────────┤
│ All types │ 5 │ 1 │ 80.00% │ │
└───────────────────┴────────┴──────┴─────────┴───────────────────────┘
Overall coverage: 80.00% (4/5 fields, 1 missing)
The table uses Python class and field names so uncovered resolvers are directly
searchable in the codebase. When name= explicitly changes a GraphQL name, the
GraphQL alias is shown in brackets. Automatic camel-casing is not repeated.
Use all mode to include Strawberry fields that use default attribute
resolution:
pytest --strawberry-coverage --strawberry-coverage-mode=all
A field counts as covered when GraphQL execution reaches its resolver or default lookup. A resolver that raises still counts. Fields skipped by a directive, omitted from the operation, or bypassed by null propagation do not. Aliases and fragments do not create additional field coordinates.
You can enforce a minimum combined percentage:
pytest --strawberry-coverage --strawberry-coverage-fail-under=90
The threshold is compared with the displayed percentage rounded to two decimal
places. Mode, threshold, and HTML options require --strawberry-coverage.
HTML report
Write the same coverage data to a self-contained HTML report:
pytest --strawberry-coverage --strawberry-coverage-html=htmlstrawberry
Open htmlstrawberry/index.html in a browser. The responsive report opens
with the overall percentage, uses Python-first names, and groups compact
single-line field rows under their type. Clear green and red rows distinguish
covered and missing fields, and missing fields are also labeled in text so the
state survives printing. In resolver mode, fields using ordinary attribute
lookup can be shown as muted yellow-gray not counted rows for context while
remaining excluded from coverage totals. Checkboxes can hide fully covered
types or reveal those excluded fields without JavaScript. For declarations
inside the pytest project root, the type header shows the Python file and each
field shows its definition line.
Fields wired through an external resolver, resolver factory, lambda, or
user-defined field extension also include a compact via ... hint. Ordinary
inline methods and framework-generated fields remain unannotated, keeping the
report focused on wiring that may not be obvious from Python source coverage.
The report follows the operating system's light or dark appearance and includes
all styles without external assets. Column labels and the current type remain
visible while scrolling long reports. A custom output directory can be passed
after =. The terminal report remains enabled.
Schema executions with different field sets or Python mappings receive separate fingerprinted tables. Executions with the same field set are combined. The final threshold uses their combined field and hit totals. Coverage from pytest-xdist workers is merged automatically.
A runnable Strawberry Django example shows how generated model fields participate in resolver coverage without adding a runtime dependency on Strawberry Django.
Subscriptions
Subscription resolver extensions are supported by graphql-core 3.3 and newer. With that capability available, subscription source and payload fields are included normally. graphql-core 3.2 does not run resolver extensions for subscriptions, so subscription-only fields are excluded and the plugin emits one warning if a subscription executes. Query and mutation coverage remains available in the same run.
Only schemas used to execute an operation during the pytest session are
reported. An observed schema with no eligible fields is 100% covered; a session
that observes no schemas is 0% covered. Reporting and threshold enforcement are
disabled under --collect-only.
Development
Install the project and its development dependencies with uv:
uv sync
Run the checks with:
uv run pytest
uv run ruff check .
uv run ruff format --check .
uv run mypy
uv build
Run the Strawberry, graphql-core, and Strawberry Django compatibility checks on Python 3.14 with:
uv run nox --tags compatibility
Releases
Release changes are proposed through pull requests containing a RELEASE.md.
After the pull request is merged into main, AutoPub prepares and publishes the
release.
Licensing
The code in this project is licensed under the MIT license. See LICENSE for more information.
Release files for pytest-strawberry 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| pytest_strawberry-0.3.0.tar.gz | 18.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| pytest_strawberry-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 39.5 kB
Release files / pytest_strawberry-0.3.0.tar.gz
| Download URL | pytest_strawberry-0.3.0.tar.gz |
|---|---|
| Size | 18.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1bdece8fcf39db3fa878ce5922b6e31d5ee5aba3145fbd631bb933db369907a5
|
|
BLAKE2b-256 checksum How to use checksums |
a1c93a9e094159dca26a57dfccde66d9a3c112b0f5399c957eabe1e99be184d4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / pytest_strawberry-0.3.0-py3-none-any.whl
| Download URL | pytest_strawberry-0.3.0-py3-none-any.whl |
|---|---|
| Size | 20.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
febbd73660bfacac313dc99f3c6440100f9fed6bf992f93cbb67fdb7af2ba112
|
|
BLAKE2b-256 checksum How to use checksums |
c745648c651d1dd16c107c0950c6365611926b5399e33a816b3fa5a8fa017c92
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|