Skip to main content

A pytest fixture for high-precision SQL testing in SQLAlchemy.

Project description

pytest-capquery

Build Status Codecov Python Version License

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 AsyncSession environments.

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:

  1. Open an Issue: Before writing any code, please open an issue to discuss the feature, enhancement, or bug fix you have in mind.
  2. Contribute the Code: Once discussed, fork the repository, create your branch, make your changes, and submit a Pull Request.
  3. 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

pytest_capquery-0.2.0.tar.gz (12.9 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytest_capquery-0.2.0-py3-none-any.whl (11.7 kB view details)

Uploaded Python 3

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

Hashes for pytest_capquery-0.2.0.tar.gz
Algorithm Hash digest
SHA256 feffe115d59eca5ca9886aa97b2155f381cb1982833748d473cb4e2382cacc97
MD5 c63301062153c2c8bac5ad27491bee1e
BLAKE2b-256 4f664f9afdec7b1ddea0a0f18a99e83aa2383d16f4bc487b22cfaa2df4f67ea7

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_capquery-0.2.0.tar.gz:

Publisher: publish.yml on fmartins/pytest-capquery

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file pytest_capquery-0.2.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pytest_capquery-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 1384cb0fe7455b4d2abd8718145761b85d9a5ef1b52eb75590da91c6a9949882
MD5 97bc40ddf942902c8fb1156191bb369e
BLAKE2b-256 2f9f5270823dc8e2b1804a91bea191dcff18cc793981cc8cad837f6232a1ae98

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_capquery-0.2.0-py3-none-any.whl:

Publisher: publish.yml on fmartins/pytest-capquery

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page