# pytest-snap
A simple snapshot testing library implemented as a pytest plugin.
`pytest-snap` allows you to easily create and compare text-based snapshots of test data by writing `assert snap(".json", content)` where content is a string. The library handles file creation on first run and comparison on subsequent runs.
## Why another snapshot testing library?
There are many great snapshot testing libraries out there, like [syrupy](https://github.com/syrupy-project/syrupy), [pytest-snapshot](https://github.com/joseph-roitman/pytest-snapshot) or [pytest-insta](https://github.com/vberlier/pytest-insta).
This one is for you if:
* You want to snapshot your data as txt. **You** want to control the serialization of your data to text.
* You like the simple workflow of this library (see section "Quick Start" in this README)
And optionally:
* You are producing numerical data and want to compare it only to some significant digits. Check out the section "Optional feature: Rounding floating point numbers" in this README.
## Installation
Install `pytest-snap` using pip:
```bash
pip install pytest-snap
```
Or using uv:
```bash
uv add --dev pytest-snap
```
## Quick Start
1. Add the `snap` fixture as an argument to your test functions:
```python
def test_api_response(snap):
response_data = {"user": "john", "status": "active"}
response_json = json.dumps(response_data, indent=2)
# This will create a snapshot file on first run
assert snap(".json", response_json)
def test_multiple_formats(snap):
# You can create multiple snapshots from one test function
assert snap(".json", json.dumps({"message": "Hello"})) # _0.json
assert snap(".json", json.dumps({"message": "Hello again"})) # _1.json
assert snap(".html", "<div><h1>Hello World</h1></div>") # _2.html
```
2. Run your tests:
```bash
pytest
```
On the first run, `pytest-snap` will create snapshot files in a `__snapshots__` directory next to your test files:
```
tests/
├── test_example.py
└── __snapshots__/
├── test_example__test_api_response_0.json
└── test_example__test_html_output_0.html
```
You should commit these snapshot files to your version control system (e.g. git).
3. On subsequent `pytest`runs, `pytest-snap` compares your test output against the stored snapshots and fails if they don't match, showing you a clear diff. So whenever you refactor your code, you can run the snapshot tests and as long as the tests pass, you can be confident that your code changes are safe.
4. Sometimes your code change is no refactor. You know that you want to change your code in a way which changes the snapshot files. Change your code, and then run pytest with the `--snap-update` flag to update the snapshots. Use your version control system to see how the snapshots have changed (e.g. git difftool).
```bash
pytest --snap-update
```
## File Organization
`pytest-snap` organizes snapshot files in a predictable structure:
```
your_project/
├── tests/
├── test_api.py
├── test_utils.py
└── __snapshots__/
├── test_api__test_user_endpoint_0.json
├── test_api__test_error_handling_0.json
├── test_utils__test_format_data_0.txt
└── test_utils__test_format_data_1.html
```
The naming convention is: `{test_file_name}__{test_function_name}_{call_index}{extension}`
## Error Messages and Debugging
When a snapshot doesn't match, `pytest-snap` provides a clear error message:
```
Snapshot mismatch for unit_test__test_very_long_0.txt
Snapshot file: /home/username/cool-project/tests/__snapshots__/unit_test__test_very_long_0.txt
In line 211 there is a mismatch between the snapshot and the current result:
expected: 'I like python very much'
current: 'I like python very much indeed'
Subsequent lines may also differ but will not be checked.
To update this snapshot, run: pytest --snap-update
============================================================== short test summary info ===============================================================
FAILED tests/unit_test.py::test_very_long - Failed: Snapshot mismatch for unit_test__test_very_long_0.txt
```
## Type hints
You can use a type hint for the `snap` fixture if you want to:
```python
from pytest_snap import SnapshotFixture
def test_api_response(snap : SnapshotFixture):
assert snap(".json", json.dumps({"message": "Hello"}))
```
## Optional feature: Rounding floating point numbers
The `snap` fixture has an optional argument `digits` which allows you to round all floats within your snapshot string to `digits` significant digits.
```python
def test_number(snap):
assert snap(".txt", "pi=3.14159!", digits=3)
# will result in snapshot file with content "pi=3.14!"
```
Note that the problem to identify which parts of a string are actually floats is ambiguous.
However, the current implementation should work well in a lot of cases, and especially if your string was
generated by a json dump. Note that timestamps, IP addresses, and URLs are recognized and will not be altered.
## Development
* Make sure you have `uv` installed.
* To run tests: `uv run pytest`
## Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
Raw data
{
"_id": null,
"home_page": null,
"name": "pytest-snap",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.10",
"maintainer_email": null,
"keywords": "pytest-plugin, pytest, testing, snapshot, snapshot-testing",
"author": "Mario Theers",
"author_email": "Mario Theers <mario.theers@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/26/f6/c05f962a04c248b0c9cea64c04fb0431bc549683c77f991e83e3e4174f5a/pytest_snap-0.2.0.tar.gz",
"platform": null,
"description": "# pytest-snap\n\nA simple snapshot testing library implemented as a pytest plugin.\n\n`pytest-snap` allows you to easily create and compare text-based snapshots of test data by writing `assert snap(\".json\", content)` where content is a string. The library handles file creation on first run and comparison on subsequent runs.\n\n## Why another snapshot testing library?\n\nThere are many great snapshot testing libraries out there, like [syrupy](https://github.com/syrupy-project/syrupy), [pytest-snapshot](https://github.com/joseph-roitman/pytest-snapshot) or [pytest-insta](https://github.com/vberlier/pytest-insta).\n\nThis one is for you if:\n\n* You want to snapshot your data as txt. **You** want to control the serialization of your data to text.\n* You like the simple workflow of this library (see section \"Quick Start\" in this README)\n\nAnd optionally:\n* You are producing numerical data and want to compare it only to some significant digits. Check out the section \"Optional feature: Rounding floating point numbers\" in this README.\n\n## Installation\n\nInstall `pytest-snap` using pip:\n\n```bash\npip install pytest-snap\n```\n\nOr using uv:\n\n```bash\nuv add --dev pytest-snap\n```\n\n## Quick Start\n\n1. Add the `snap` fixture as an argument to your test functions:\n\n```python\ndef test_api_response(snap):\n response_data = {\"user\": \"john\", \"status\": \"active\"}\n response_json = json.dumps(response_data, indent=2)\n # This will create a snapshot file on first run\n assert snap(\".json\", response_json)\n\n\ndef test_multiple_formats(snap):\n # You can create multiple snapshots from one test function\n assert snap(\".json\", json.dumps({\"message\": \"Hello\"})) # _0.json\n assert snap(\".json\", json.dumps({\"message\": \"Hello again\"})) # _1.json\n assert snap(\".html\", \"<div><h1>Hello World</h1></div>\") # _2.html\n```\n\n\n2. Run your tests:\n\n```bash\npytest\n```\n\nOn the first run, `pytest-snap` will create snapshot files in a `__snapshots__` directory next to your test files:\n\n```\ntests/\n\u251c\u2500\u2500 test_example.py\n\u2514\u2500\u2500 __snapshots__/\n \u251c\u2500\u2500 test_example__test_api_response_0.json\n \u2514\u2500\u2500 test_example__test_html_output_0.html\n```\n\nYou should commit these snapshot files to your version control system (e.g. git).\n\n3. On subsequent `pytest`runs, `pytest-snap` compares your test output against the stored snapshots and fails if they don't match, showing you a clear diff. So whenever you refactor your code, you can run the snapshot tests and as long as the tests pass, you can be confident that your code changes are safe.\n\n4. Sometimes your code change is no refactor. You know that you want to change your code in a way which changes the snapshot files. Change your code, and then run pytest with the `--snap-update` flag to update the snapshots. Use your version control system to see how the snapshots have changed (e.g. git difftool).\n\n```bash\npytest --snap-update\n```\n\n\n## File Organization\n\n`pytest-snap` organizes snapshot files in a predictable structure:\n\n```\nyour_project/\n\u251c\u2500\u2500 tests/\n \u251c\u2500\u2500 test_api.py\n \u251c\u2500\u2500 test_utils.py\n \u2514\u2500\u2500 __snapshots__/\n \u251c\u2500\u2500 test_api__test_user_endpoint_0.json\n \u251c\u2500\u2500 test_api__test_error_handling_0.json\n \u251c\u2500\u2500 test_utils__test_format_data_0.txt\n \u2514\u2500\u2500 test_utils__test_format_data_1.html\n```\n\nThe naming convention is: `{test_file_name}__{test_function_name}_{call_index}{extension}`\n\n## Error Messages and Debugging\n\nWhen a snapshot doesn't match, `pytest-snap` provides a clear error message:\n\n```\nSnapshot mismatch for unit_test__test_very_long_0.txt\nSnapshot file: /home/username/cool-project/tests/__snapshots__/unit_test__test_very_long_0.txt\n\nIn line 211 there is a mismatch between the snapshot and the current result:\nexpected: 'I like python very much'\ncurrent: 'I like python very much indeed'\nSubsequent lines may also differ but will not be checked.\n\nTo update this snapshot, run: pytest --snap-update\n============================================================== short test summary info ===============================================================\nFAILED tests/unit_test.py::test_very_long - Failed: Snapshot mismatch for unit_test__test_very_long_0.txt\n```\n\n## Type hints\nYou can use a type hint for the `snap` fixture if you want to:\n\n```python\nfrom pytest_snap import SnapshotFixture\n\ndef test_api_response(snap : SnapshotFixture):\n assert snap(\".json\", json.dumps({\"message\": \"Hello\"}))\n```\n\n\n## Optional feature: Rounding floating point numbers\nThe `snap` fixture has an optional argument `digits` which allows you to round all floats within your snapshot string to `digits` significant digits.\n\n```python\ndef test_number(snap):\n assert snap(\".txt\", \"pi=3.14159!\", digits=3)\n # will result in snapshot file with content \"pi=3.14!\"\n```\n\nNote that the problem to identify which parts of a string are actually floats is ambiguous.\nHowever, the current implementation should work well in a lot of cases, and especially if your string was\ngenerated by a json dump. Note that timestamps, IP addresses, and URLs are recognized and will not be altered.\n\n\n\n## Development\n\n* Make sure you have `uv` installed.\n* To run tests: `uv run pytest`\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n",
"bugtrack_url": null,
"license": null,
"summary": "A text-based snapshot testing library implemented as a pytest plugin",
"version": "0.2.0",
"project_urls": {
"Homepage": "https://github.com/thomasfermi/pytest-snap",
"Issues": "https://github.com/thomasfermi/pytest-snap/issues"
},
"split_keywords": [
"pytest-plugin",
" pytest",
" testing",
" snapshot",
" snapshot-testing"
],
"urls": [
{
"comment_text": null,
"digests": {
"blake2b_256": "ea13d19a747213aa43b15c5a8f4ccc82b025455ab88e03293778592de9d41147",
"md5": "d7b7359b82049b68afa896d3df2b5041",
"sha256": "f0a1ddbc2d20f5ad29a97f16a7c5df3199e3c1348bb1ef3d814e6cb5bc778e54"
},
"downloads": -1,
"filename": "pytest_snap-0.2.0-py3-none-any.whl",
"has_sig": false,
"md5_digest": "d7b7359b82049b68afa896d3df2b5041",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.10",
"size": 7753,
"upload_time": "2025-08-21T17:53:27",
"upload_time_iso_8601": "2025-08-21T17:53:27.135534Z",
"url": "https://files.pythonhosted.org/packages/ea/13/d19a747213aa43b15c5a8f4ccc82b025455ab88e03293778592de9d41147/pytest_snap-0.2.0-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": null,
"digests": {
"blake2b_256": "26f6c05f962a04c248b0c9cea64c04fb0431bc549683c77f991e83e3e4174f5a",
"md5": "da88b724bf3547c9fad5541a165c2376",
"sha256": "102ead0f852ffbaee65e56735debff2694142d9013c03c3a2dd9ef5f7b2f2ffc"
},
"downloads": -1,
"filename": "pytest_snap-0.2.0.tar.gz",
"has_sig": false,
"md5_digest": "da88b724bf3547c9fad5541a165c2376",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.10",
"size": 5928,
"upload_time": "2025-08-21T17:53:28",
"upload_time_iso_8601": "2025-08-21T17:53:28.565731Z",
"url": "https://files.pythonhosted.org/packages/26/f6/c05f962a04c248b0c9cea64c04fb0431bc549683c77f991e83e3e4174f5a/pytest_snap-0.2.0.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-08-21 17:53:28",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "thomasfermi",
"github_project": "pytest-snap",
"travis_ci": false,
"coveralls": false,
"github_actions": false,
"lcname": "pytest-snap"
}