A pytest fixture for high-precision SQL testing in SQLAlchemy.
Project description
pytest-capquery
Testing your business logic is good, but testing your database interactions is critical.
pytest-capquery treats your SQL queries as first-class citizens in your test suite. By asserting
the exact queries executed, you create living documentation of what is truly happening behind the
scenes. This guarantees deterministic performance, catches N+1 regressions instantly, and ensures
your application behaves exactly as intended.
Designed for modern Python applications, pytest-capquery is a strict, strongly-typed SQLAlchemy
pytest plugin that enforces exact chronological query execution, validating precise SQL strings,
parameter bindings, and transaction boundaries (BEGIN, COMMIT, ROLLBACK).
Key Features
- Contextual Isolation: Use the
capture()context manager to track queries locally without global state leakage or manual resets. - Strict Timeline Assertion: Validate the exact chronological sequence of SQL strings and transaction events.
- Heuristic N+1 Guards: Use "loose assertion" mode to enforce maximum query counts without binding tests to fragile ORM implementation details.
- Deterministic Parameter Matching: Ensures cross-dialect equality for parameter structures.
- Async Ready: Seamlessly integrates with standard and
AsyncSessionenvironments.
Used By
pytest-capquery is actively used to protect the database performance of:
Installation
Install via pip:
pip install pytest-capquery
Quick Start
The capquery fixture captures all SQLAlchemy statements executed by your code. The best practice
is to use the capture() context manager to isolate specific execution phases.
1. Preventing N+1 Queries (Loose Assertion)
If you want to protect a block of code against N+1 regressions without hardcoding exact SQL strings, you can enforce a strict expected query count at the context boundary:
def test_fetch_users(db_session, capquery):
# Enforce that exactly 1 query is executed inside this block.
# If a lazy-loading loop triggers extra queries, this will raise an AssertionError.
with capquery.capture(expected_count=1):
users = db_session.query(User).all()
for user in users:
_ = user.address
2. Asserting Exact SQL Execution (Strict Assertion)
For mission-critical operations, you can capture a phase and rigorously assert the exact SQL and parameters executed:
def test_update_user_status(db_session, capquery):
with capquery.capture() as phase:
user = db_session.query(User).filter_by(id=1).first()
user.status = "active"
db_session.commit()
# Verify the precise chronological timeline of the transaction
phase.assert_executed_queries(
"BEGIN",
(
"""
SELECT users.id, users.status
FROM users
WHERE users.id = ?
""",
(1,)
),
(
"""
UPDATE users SET status=? WHERE users.id = ?
""",
("active", 1)
),
"COMMIT"
)
Contributing
We welcome contributions to make this plugin even better! To ensure a smooth process, please follow these steps:
- Open an Issue: Before writing any code, please open an issue to discuss the feature, enhancement, or bug fix you have in mind.
- Contribute the Code: Once discussed, fork the repository, create your branch, make your changes, and submit a Pull Request.
- Review & Release: All PRs will be reviewed. Once approved and merged, the release process will be managed by the maintainer.
Developer Setup
To get your local environment ready for contribution, run the following commands:
# Clone the repository
git clone https://github.com/fmartins/pytest-capquery.git
cd pytest-capquery
# Install Python, dependencies, and pre-commit hooks
make setup
# Run the full test suite (handles DB spin-up and coverage)
make test
License
This project is licensed under the Creative Commons Attribution-NonCommercial-ShareAlike 4.0 International (CC BY-NC-SA 4.0).
Author: Felipe Cardoso Martins
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pytest_capquery-0.2.0.tar.gz.
File metadata
- Download URL: pytest_capquery-0.2.0.tar.gz
- Upload date:
- Size: 12.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
feffe115d59eca5ca9886aa97b2155f381cb1982833748d473cb4e2382cacc97
|
|
| MD5 |
c63301062153c2c8bac5ad27491bee1e
|
|
| BLAKE2b-256 |
4f664f9afdec7b1ddea0a0f18a99e83aa2383d16f4bc487b22cfaa2df4f67ea7
|
Provenance
The following attestation bundles were made for pytest_capquery-0.2.0.tar.gz:
Publisher:
publish.yml on fmartins/pytest-capquery
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_capquery-0.2.0.tar.gz -
Subject digest:
feffe115d59eca5ca9886aa97b2155f381cb1982833748d473cb4e2382cacc97 - Sigstore transparency entry: 1223022428
- Sigstore integration time:
-
Permalink:
fmartins/pytest-capquery@b5211e546d24a1f45326b8a726004140410b12a9 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/fmartins
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b5211e546d24a1f45326b8a726004140410b12a9 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pytest_capquery-0.2.0-py3-none-any.whl.
File metadata
- Download URL: pytest_capquery-0.2.0-py3-none-any.whl
- Upload date:
- Size: 11.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1384cb0fe7455b4d2abd8718145761b85d9a5ef1b52eb75590da91c6a9949882
|
|
| MD5 |
97bc40ddf942902c8fb1156191bb369e
|
|
| BLAKE2b-256 |
2f9f5270823dc8e2b1804a91bea191dcff18cc793981cc8cad837f6232a1ae98
|
Provenance
The following attestation bundles were made for pytest_capquery-0.2.0-py3-none-any.whl:
Publisher:
publish.yml on fmartins/pytest-capquery
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_capquery-0.2.0-py3-none-any.whl -
Subject digest:
1384cb0fe7455b4d2abd8718145761b85d9a5ef1b52eb75590da91c6a9949882 - Sigstore transparency entry: 1223022492
- Sigstore integration time:
-
Permalink:
fmartins/pytest-capquery@b5211e546d24a1f45326b8a726004140410b12a9 -
Branch / Tag:
refs/heads/main - Owner: https://github.com/fmartins
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@b5211e546d24a1f45326b8a726004140410b12a9 -
Trigger Event:
push
-
Statement type: