Skip to main content

pytest-snapmock

Pytest Snapshot License

Overview

This library provides a convenient way to generate snapshots for monkeypatched objects in your tests using pytest. Longgone are the days trying to come up with mock lambdas and data.

Features

  • Snapshot Generation: Automatically create snapshots of monkeypatched objects.
  • Easy Integration: Seamlessly integrates with existing pytest workflows.
  • Diff Reporting: Clear reporting on differences between current and expected snapshots.

Installation

You can install the library via pip (soon):

pip install pytest-snapmock

Usage

snapit

Take a function like the following that changes based on when it's called:

import datetime

def two_days_from_now():
    return datetime.today() + datetime.timedelta(days=2)

To write a unittest, you would have to patch datetime.today to return a fixed date:

def test_two_days_from_now(monkeypatch):
    monkeypatch.setattr(mymodule.datetime, 'today', lambda: datetime.date(2024, 10, 31))
    assert two_days_from_now() == datetime.date(2024, 11, 2)

Instead, it can be written as:

def test_two_days_from_now(snapmock):
    snapmock.snapit(mymodule.datetime, 'today')
    assert two_days_from_now() == datetime.date(2024, 11, 2)

And then generate the snapshot

pytest --snapshot-mocks

Verify the snapshot file

cat __snapshot__/test_two_days_from_now_mymodule.datetime_today_0.snap

And then just run your tests like normal:

pytest

A more realistic scenario

Let's say you have a function that loads data from a url (or file, db, etc).

# ridership.py
import pandas as pd

def get_nyc_ridership():
    df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/refs/heads/master/MTA_Ridership_by_DATA_NY_GOV.csv')
    return df


def busiest_day_by_year():
    df = get_nyc_ridership()
    df['Date'] = pd.to_datetime(df['Date'])
    return df.groupby(df['Date'].dt.year)['Subways: Total Estimated Ridership']

Writing the unittest for busiest_day_by_year means you need to mock the download via read_csv or get_nyc_ridership. Which can be done with adding a sample file or handwriting a dataframe in the test directly like:

from unittest.mock import patch

import pandas as pd

import ridership


def test_busiest_day_from_file(monkeypatch):
    monkeypatch.settattr(ridership, 'get_nyc_ridership', lambda: pd.read_csv(__file__.parent / 'ridership_data.csv'))
    assert busiest_day_by_year() == pd.Series(...)


def test_busiest_day(monkeypatch):
    data = pd.DataFrame({'Date': ['03/01/2020',...],
                         'Subways: Total Estimated Ridership': [100,...],
                         ...})
    monkeypatch.settattr(ridership, 'get_nyc_ridership', lambda: data)
    assert busiest_day_by_year() == pd.Series(...)

pytest-snapmock takes care of adding the sample file and patching for you. The above can be done:

import ridership


def test_busiest_day(snapmock):
    snapmock.snapit(ridership, 'get_nyc_ridership')
    assert busiest_day_by_year()

Serialization

pytest-snapmock serializes the inputs and output of the functions it mocks. It uses the serialized string of the inputs to generate a hash. This hash is used to determine if the function call has been changed and the snapshots need to be regenerated. json is used by default. To use a custom serializer for the output and args, use the output_serializer and arg_sreializer, respectively. The serializer must have the following interface:

class Serializer:
    def loads(self, obj):
        pass

    def dumps(self, obj):
        pass

Snapshot Management

Snapshots are stored in a __snapshot__ directory in the same directory as the test and are named based on the test and the name of mocked object. You can easily manage them by deleting or modifying snapshot files directly.

Contribution

Contributions are welcome! Please fork the repository and submit a pull request. For large changes, please open an issue first to discuss your proposed changes.

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

Thanks to the contributors of pytest, pytest-snapshot and syrupy for the inspiration!

Metadata

Release files for pytest-snapmock 0.0.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for pytest-snapmock 0.0.1
File Size Uploaded
pytest_snapmock-0.0.1.tar.gz 10.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for pytest-snapmock 0.0.1
File Interpreter ABI Platform
pytest_snapmock-0.0.1-py3-none-any.whl Python 3 none any Details

Total release size: 17.8 kB

Release files / pytest_snapmock-0.0.1.tar.gz

Download URL pytest_snapmock-0.0.1.tar.gz
Size 10.9 kB
Tags Source
SHA-256 checksum
How to use checksums
fabed093091cce3360d0e3f4953f2ea6953ac99db241c5bffd9d822064f3bed9
BLAKE2b-256 checksum
How to use checksums
fbe1e975129e06892b991d701aec67bce17f271c5f35a8c054edbdd000eb0ea7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/5.1.1 CPython/3.12.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 15, 2024.

Transparency log

Release files / pytest_snapmock-0.0.1-py3-none-any.whl

Download URL pytest_snapmock-0.0.1-py3-none-any.whl
Size 6.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
06037540619e017933839b50c689dc653fd95ce5b0037c5345adb0cf741295fa
BLAKE2b-256 checksum
How to use checksums
a801dccf1c875bbe0dd2ba2fa71eb21716e02cd31a16fd8fc0425dbcf114d9ff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/5.1.1 CPython/3.12.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Nov 15, 2024.

Transparency log

Release history Release notifications | RSS feed

This release

0.0.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page