Skip to main content

A text-based snapshot testing library implemented as a pytest plugin

Project description

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, pytest-snapshot or 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:

pip install pytest-snap

Or using uv:

uv add --dev pytest-snap

Quick Start

  1. Add the snap fixture as an argument to your test functions:
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
  1. Run your tests:
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).

  1. On subsequent pytestruns, 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.

  2. 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).

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:

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.

def test_number(snap):
    assert snap(".txt", "pi=3.14159!", digits=3)
    # will result in snapshot file with content "pi=3.14!"

Note that identifying which parts of a string are actually floats is inherently ambiguous. The current implementation may work reasonably well for many cases, particularly json dumps, but should be used with caution. It attempts to preserve timestamps, dates, IP addresses, SemVer and URLs, though edge cases may not be handled correctly.

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.

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_snap-0.2.2.tar.gz (6.0 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pytest_snap-0.2.2-py3-none-any.whl (7.8 kB view details)

Uploaded Python 3

File details

Details for the file pytest_snap-0.2.2.tar.gz.

File metadata

  • Download URL: pytest_snap-0.2.2.tar.gz
  • Upload date:
  • Size: 6.0 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.8.0

File hashes

Hashes for pytest_snap-0.2.2.tar.gz
Algorithm Hash digest
SHA256 fe0d33c49257b59a1bf42cda5a5a37d0d9f7c6916442c25ab0aab2af1517b324
MD5 fa568790d19674d83a733454036e1553
BLAKE2b-256 7f42669af29099f72e81a36a6bd16cf70d173e0812ad04a5b57e864eb7ecaefd

See more details on using hashes here.

File details

Details for the file pytest_snap-0.2.2-py3-none-any.whl.

File metadata

File hashes

Hashes for pytest_snap-0.2.2-py3-none-any.whl
Algorithm Hash digest
SHA256 2fbf0256393d76fa5f9f7f6c7b22a68cd4577d1f813361efcc208565a983161b
MD5 074b90e08c7b5766b2c923c91b28ab44
BLAKE2b-256 c7e148a891fbd269b7e3510b24d43b18c05fe8a5c701ecce68e6552f7c6291ae

See more details on using hashes here.

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