Snapshots for your mocks.
Project description
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!
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
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
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fabed093091cce3360d0e3f4953f2ea6953ac99db241c5bffd9d822064f3bed9
|
|
| MD5 |
698e6b81a27763f5dd79bff2f79c655b
|
|
| BLAKE2b-256 |
fbe1e975129e06892b991d701aec67bce17f271c5f35a8c054edbdd000eb0ea7
|
Provenance
The following attestation bundles were made for pytest_snapmock-0.0.1.tar.gz:
Publisher:
python-package.yml on postelrich/pytest-snapmock
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_snapmock-0.0.1.tar.gz -
Subject digest:
fabed093091cce3360d0e3f4953f2ea6953ac99db241c5bffd9d822064f3bed9 - Sigstore transparency entry: 149027753
- Sigstore integration time:
-
Permalink:
postelrich/pytest-snapmock@029ce126c06766ee74d70d18f1b8b012f95bfb48 -
Branch / Tag:
refs/tags/0.0.1 - Owner: https://github.com/postelrich
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-package.yml@029ce126c06766ee74d70d18f1b8b012f95bfb48 -
Trigger Event:
push
-
Statement type:
File details
Details for the file pytest_snapmock-0.0.1-py3-none-any.whl.
File metadata
- Download URL: pytest_snapmock-0.0.1-py3-none-any.whl
- Upload date:
- Size: 6.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/5.1.1 CPython/3.12.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
06037540619e017933839b50c689dc653fd95ce5b0037c5345adb0cf741295fa
|
|
| MD5 |
a6c79f40dd5b3966bb2e75aff15bf5da
|
|
| BLAKE2b-256 |
a801dccf1c875bbe0dd2ba2fa71eb21716e02cd31a16fd8fc0425dbcf114d9ff
|
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
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pytest_snapmock-0.0.1-py3-none-any.whl -
Subject digest:
06037540619e017933839b50c689dc653fd95ce5b0037c5345adb0cf741295fa - Sigstore transparency entry: 149027754
- Sigstore integration time:
-
Permalink:
postelrich/pytest-snapmock@029ce126c06766ee74d70d18f1b8b012f95bfb48 -
Branch / Tag:
refs/tags/0.0.1 - Owner: https://github.com/postelrich
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
python-package.yml@029ce126c06766ee74d70d18f1b8b012f95bfb48 -
Trigger Event:
push
-
Statement type: