Skip to main content

pytest plugin to record and replay ADBC database queries

Project description

pytest-adbc-replay

[ Docs ]

Record/replay testing for ADBC database queries, as a pytest plugin.

What / Why

Works like VCR.py and pytest-recording: the first run records live queries to cassette files on disk, subsequent runs replay from those cassettes. CI tests pass with no live warehouse connection, and query changes are visible as plain diffs in pull requests (.sql files are human-readable and committed to version control).

Installation

pip install pytest-adbc-replay

Quick Start

For this example we'll use the DuckDB ADBC driver (no credentials needed):

pip install adbc-driver-duckdb

Mocking is flexible enough to use with any ADBC driver.

pyproject.toml — tell the plugin which drivers to intercept:

[tool.pytest.ini_options]
adbc_auto_patch = ["adbc_driver_duckdb.dbapi"]

The value is the Python module path where connect() lives — for all standard ADBC drivers this is adbc_driver_<name>.dbapi.

test_example.py — mark each test and call connect() normally:

import adbc_driver_duckdb.dbapi as duckdb
import pytest


@pytest.mark.adbc_cassette("my_query")
def test_my_query():
    conn = duckdb.connect()
    with conn.cursor() as cur:
        cur.execute("SELECT 42 AS answer")
        assert cur.fetchone() == (42,)

No conftest.py needed. The plugin intercepts duckdb.connect() automatically for tests decorated with @pytest.mark.adbc_cassette.

Record cassettes on the first run:

pytest --adbc-record=once

Replay from cassettes (default — no flag needed):

pytest

Cassette Layout

tests/cassettes/
└── my_query/
    └── adbc_driver_duckdb.dbapi/
        ├── 000.sql      # human-readable normalised SQL
        ├── 000.arrow    # Arrow IPC result with schema metadata
        └── 000.json     # parameters and driver options (null when absent)

Commit the cassettes to version control — any changes appear as diffs in pull requests.

Configuration Reference

Setting Type Default Description
--adbc-record CLI flag none Record mode for this run
adbc_cassette_dir ini key tests/cassettes Directory to read/write cassettes
adbc_record_mode ini key none Persistent record mode (overridden by CLI flag)
adbc_dialect ini key (linelist) [] SQL dialect for normalisation. Bare value = global fallback, driver: dialect = per-driver. Empty = auto-detect.
adbc_auto_patch ini key (linelist) [] ADBC driver module names to auto-intercept
adbc_scrub_keys ini key (linelist) [] Parameter key names to redact from cassette .json files

Minimal pyproject.toml snippet:

[tool.pytest.ini_options]
adbc_cassette_dir = "tests/cassettes"
adbc_record_mode = "none"
adbc_dialect = []  # e.g. ["adbc_driver_snowflake.dbapi: snowflake", "adbc_driver_duckdb.dbapi: duckdb"]
adbc_auto_patch = []  # e.g. ["adbc_driver_duckdb.dbapi", "adbc_driver_snowflake.dbapi"]
adbc_scrub_keys = []  # e.g. ["token password", "adbc_driver_snowflake: account_id"]

Record Modes

Mode Behaviour
none Replay only. Raises CassetteMissError if cassette is absent (default).
once Record if cassette absent, replay if cassette present.
new_episodes Replay existing interactions, record new ones.
all Re-record everything on every run.

Scrubbing Sensitive Values

To keep credentials out of cassette files, list parameter key names in adbc_scrub_keys:

[tool.pytest.ini_options]
adbc_scrub_keys = ["token password api_key"]

Matched values become REDACTED in the .json cassette file. Per-driver form:

adbc_scrub_keys = [
    "token",
    "adbc_driver_snowflake: account_id warehouse",
]

For custom scrubbing logic, override the adbc_scrubber fixture in your conftest.py:

import pytest


@pytest.fixture(scope="session")
def adbc_scrubber():
    def scrub(params: dict | None, driver_name: str) -> dict | None:
        if not isinstance(params, dict):
            return params
        return {k: "REDACTED" if k.endswith("_key") else v for k, v in params.items()}

    return scrub

Config scrubbing runs first; the fixture callable receives the already-config-scrubbed params.

Advanced

adbc_param_serialisers is a session-scoped fixture for registering custom parameter serialisers for types not handled by default.

Full reference documentation: https://anentropic.github.io/pytest-adbc-replay

License

BSD-3-Clause

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_adbc_replay-1.0.0.tar.gz (20.5 kB view details)

Uploaded Source

Built Distribution

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

pytest_adbc_replay-1.0.0-py3-none-any.whl (25.6 kB view details)

Uploaded Python 3

File details

Details for the file pytest_adbc_replay-1.0.0.tar.gz.

File metadata

  • Download URL: pytest_adbc_replay-1.0.0.tar.gz
  • Upload date:
  • Size: 20.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pytest_adbc_replay-1.0.0.tar.gz
Algorithm Hash digest
SHA256 d74ae0a0f4afd5ef072cc70e9d1f29c60f01f9d198299a0c40ce9635e31e0c8c
MD5 8489c78315f69f2d9e2b3c3e9fe30ef8
BLAKE2b-256 c82270fb4c42adf9195ad7ecdae266a7ed9c7a49bc9d7700bbfd7f37e339b6d4

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_adbc_replay-1.0.0.tar.gz:

Publisher: release.yml on anentropic/pytest-adbc-replay

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_adbc_replay-1.0.0-py3-none-any.whl.

File metadata

File hashes

Hashes for pytest_adbc_replay-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 8d32c39c25d92bedf31d5e28b4c46bd88d3b3bc1f264b7d3c5cefe06084cb5e9
MD5 b5bab4766751a26696a15559378f72db
BLAKE2b-256 9f8ff25ce3abad369809fecfda3c80914f9cb63a781d6f0658eef748347e8e7f

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_adbc_replay-1.0.0-py3-none-any.whl:

Publisher: release.yml on anentropic/pytest-adbc-replay

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