Skip to main content

Snapshots for your mocks.

Project description

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!

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_snapmock-0.0.1.tar.gz (10.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_snapmock-0.0.1-py3-none-any.whl (6.9 kB view details)

Uploaded Python 3

File details

Details for the file pytest_snapmock-0.0.1.tar.gz.

File metadata

  • Download URL: pytest_snapmock-0.0.1.tar.gz
  • Upload date:
  • Size: 10.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/5.1.1 CPython/3.12.7

File hashes

Hashes for pytest_snapmock-0.0.1.tar.gz
Algorithm Hash digest
SHA256 fabed093091cce3360d0e3f4953f2ea6953ac99db241c5bffd9d822064f3bed9
MD5 698e6b81a27763f5dd79bff2f79c655b
BLAKE2b-256 fbe1e975129e06892b991d701aec67bce17f271c5f35a8c054edbdd000eb0ea7

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_snapmock-0.0.1.tar.gz:

Publisher: python-package.yml on postelrich/pytest-snapmock

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_snapmock-0.0.1-py3-none-any.whl.

File metadata

File hashes

Hashes for pytest_snapmock-0.0.1-py3-none-any.whl
Algorithm Hash digest
SHA256 06037540619e017933839b50c689dc653fd95ce5b0037c5345adb0cf741295fa
MD5 a6c79f40dd5b3966bb2e75aff15bf5da
BLAKE2b-256 a801dccf1c875bbe0dd2ba2fa71eb21716e02cd31a16fd8fc0425dbcf114d9ff

See more details on using hashes here.

Provenance

The following attestation bundles were made for pytest_snapmock-0.0.1-py3-none-any.whl:

Publisher: python-package.yml on postelrich/pytest-snapmock

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