Skip to content

pytest-ditto pytest-ditto

Snapshot regression testing for DataFrames in pytest, with minimal ceremony, pluggable recorders, and local or remote storage backends.

Choose a recorder for pandas or Polars DataFrames or PyArrow Tables, then compare snapshots with your library's usual assertions. Add a custom recorder for other data types; storage backends work independently of the recorder.

  • Tabular Snapshots

    Record DataFrames and Tables once, then check them with the comparison functions you already use.

  • Pluggable Recorders

    Strict JSON and YAML are built in. Plugins add Parquet, Arrow IPC, CSV and more; write a recorder for your own data types and formats.

  • Local and Remote Backends

    Store snapshots locally, on S3 or anywhere fsspec reaches, or in your own backend for a database such as Redis.

  • CLI Tools

    Manage snapshots from the command line: list, update, prune, lint, and more.

  • Checked in CI

    A committed lock file records every snapshot, so CI fails on missing or stale ones.

Quick Example

pip install "pytest-ditto[pandas]"
import ditto
import pandas as pd


@ditto.pandas.parquet
def test_sales_totals(snapshot):
    sales = pd.DataFrame({"region": ["east", "east", "west"], "amount": [10, 5, 8]})
    totals = sales.groupby("region")["amount"].sum().to_frame()
    pd.testing.assert_frame_equal(totals, snapshot(totals, key="totals"))

The mark selects Parquet; snapshot() handles storage and returns the recorded DataFrame. The first run records the result, and later runs compare against it. Run ditto verify in CI so a missing snapshot fails instead of being recorded again. See the pandas, Polars and PyArrow guides for their recorders and format limitations.

Other data types

Strict JSON works without a recorder plugin:

pip install pytest-ditto
def summarise(prices):
    return {"count": len(prices), "total": sum(prices)}


def test_summarise(snapshot):
    result = summarise([3, 4.5])
    assert result == snapshot(result, key="summary")

Use a custom recorder for other types that you can serialise and read back for comparison, and a storage backend to choose where their snapshots go.

Where to start

Get Started CLI Reference