pytest-snapmock
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
pytestworkflows. - 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)
| File | Size | Uploaded | |
|---|---|---|---|
| pytest_snapmock-0.0.1.tar.gz | 10.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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 logRelease 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