Skip to main content

A snapshot library for python optimized for easy of use, human readable snapshots and enabling decoupling of chained integration tests.

Project description

Snappylapy

Welcome to Snappylapy, a powerful and intuitive snapshot testing plugin for Python's pytest framework. Snappylapy simplifies the process of capturing and verifying snapshots of your data, ensuring your code behaves as expected across different runs. With Snappylapy, you can save snapshots in a human-readable format and deserialize them for robust integration testing, providing a clear separation layer to help isolate errors and maintain code integrity.

Installation

To get started with Snappylapy, install the package via pip, uv or poetry:

pip install snappylapy
uv add snappylapy
poetry add snappylapy

Key Features

  • Human-Readable Snapshots: Save snapshots in a format that's easy to read and understand, making it simpler to review changes and debug issues.
  • Serialization and Deserialization: Snapshots can be serialized and deserialized, allowing for flexible and reusable test cases.
  • Easy to Use: Seamlessly integrates with pytest, enabling you to capture and verify snapshots with minimal setup. The fully typed fixtures and rich editor support provide intuitive code completion and guidance, making your workflow faster and more productive.
  • Customizable Output: Store snapshots in a location (static or dynamic) of your choice, enabling you to organize and manage your test data effectively.
  • Editor Integration: Can show a diff comparison in VS code when a snapshot test fails, for easy comparison between test results and snapshots.

Benefits of Snapshot Testing

Snapshot testing is a powerful technique for verifying the output of your code by comparing it to a stored snapshot. This approach offers several benefits, including:

  • Immutability Verification: Quickly detect unintended changes or regressions by comparing current output to stored snapshots.
  • Faster Test Creation: Simplify the process of writing and maintaining tests by capturing snapshots once and letting the framework handle comparisons.
  • Documentation: Use snapshots as a form of documentation, providing a clear record of expected output and behavior.
  • Version Control Integration: Include snapshots in your version control system to aid in code reviews and track changes over time.
  • Pull Request Reviews: Enhance PR reviews by showing exactly how changes affect the application's output, ensuring thorough and effective evaluations.

Why Snappylapy?

When working on a test suite for a project, it’s important to ensure tests are independent. This is to avoid situations where changes in one part of the code cause failures in tests for other unrelated areas, making it challenging to isolate and fix errors. Snappylapy addresses this by providing a mechanism to capture snapshots of your data and use them in your later tests, ensuring that each component can be tested independently. While also making sure that they are dependent enought to test the integration between them. It provides serialization and deserialization of the snapshots, making it easy to reuse them in different test cases. This is aimed at function working with large and complex data structures (dataframes or large nested dictionaries.)

Example

test_expect_snapshot_dict.py

from snappylapy import Expect

def generate_dict(size: int) -> dict[str, int]:
    """Function to test."""
    return {f"key_{i}": i for i in range(size)}

def test_snapshot_dict(expect: Expect):
    """Test snapshot with dictionary data."""
    data: dict = generate_dict(100)
    expect(data).to_match_snapshot()
    # or expect.dict(data).to_match_snapshot()

In this example, snappylapy captures the output of my_function and compares it against a stored snapshot. If the output changes unexpectedly, pytest will flag the test, allowing you to review the differences and ensure your code behaves as expected.

Snappylapy can use the snapshots created for inputs in another test. You can think of it as automated/easier mock data generation and management.

test_expect_and_loadsnapshot.py

import pytest
from snappylapy import Expect, LoadSnapshot

def test_snapshot_dict(expect: Expect):
    """Test snapshot with dictionary data.****"""
    expect({
        "name": "John Doe",
        "age": 31
    }).to_match_snapshot()

@pytest.mark.snappylapy(depends=[test_snapshot_dict])
def test_load_snapshot_from_file(load_snapshot: LoadSnapshot):
    """Test loading snapshot data created in test_snapshot_dict from a file using the deserializer."""
    data = load_snapshot.dict()
    # Normally you would use the data as an input for some other function
    # For demonstration, we will just assert the data matches the expected snapshot
    assert data == {"name": "John Doe", "age": 31}

This can be great for external dependencies, for example an AI service, that might change response over time. With this approach we can isolate the changes to the service and still make succeding tests pass.

The output structure

The results is split into two folders, for ease of comparison, and for handling stochastic/variable outputs (timestamps, generated ids, llm outputs, third party api responses etc).

  • test_results: Updated every time the tests is ran. Compare with snapshots when doing snapshot style assertions. Add this to your .gitignore file.
  • snapshots: Updated only when --snapshot-update flag is used when running the test suite. Commit this to your version control system.

Usage

Snapshots can be updated when running pytest:

pytest --snapshot-update

Alternatively, you can use the CLI command to update snapshots:

snappylapy update

Fixtures and roadmap

Registers pytest fixtures:

  • expect
  • load_snapshot

Supported data types

  • ✅ .txt - if you provide a string
  • ✅ .json - for all other objects
  • ✅ custom (decode the data yourself and provide a file extension)

Supported data types to snapshot test

Snappylapy uses jsonpickle to serialize into json, this means that it can handle almost any Python object out of the box, including:

  • Built-in types: str, int, float, bool, None
  • Collections: list, tuple, set, dict
  • NumPy arrays and pandas DataFrames (with optional dependencies)
  • Custom classes (with jsonpickle support)

It is also possible to serialize objects yourself and provide them as a string or bytes data. Then it will be stored and loaded as-is. This means that with snappylapy it is possible to serialize and deserialize any Python object, even those not natively supported.

Snappylapy is your go-to tool for efficient and reliable snapshot testing in Python. By maintaining clear boundaries between different parts of your code, Snappylapy helps you isolate errors, streamline debugging, and ensure your code remains robust and maintainable.

Contributing

We welcome contributions to Snappylapy! If you have ideas for new features, improvements, or bug fixes, please open an issue or submit a pull request on our GitHub repository. We appreciate your feedback and support in making Snappylapy even better for the community.

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

snappylapy-0.6.1.tar.gz (39.3 kB view details)

Uploaded Source

Built Distribution

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

snappylapy-0.6.1-py3-none-any.whl (37.5 kB view details)

Uploaded Python 3

File details

Details for the file snappylapy-0.6.1.tar.gz.

File metadata

  • Download URL: snappylapy-0.6.1.tar.gz
  • Upload date:
  • Size: 39.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for snappylapy-0.6.1.tar.gz
Algorithm Hash digest
SHA256 568b9564e228d49841193f053587504f25329301437a625d36c357f25ea8fbb2
MD5 3d5c8c2267f61b24f0b532ee0a9ac031
BLAKE2b-256 d07ffcbadd90199c4efceaeeca4e96b9d38328162fcffac9f08cbd8b9ac4901d

See more details on using hashes here.

Provenance

The following attestation bundles were made for snappylapy-0.6.1.tar.gz:

Publisher: release.yaml on martinmoldrup/snappylapy

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file snappylapy-0.6.1-py3-none-any.whl.

File metadata

  • Download URL: snappylapy-0.6.1-py3-none-any.whl
  • Upload date:
  • Size: 37.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.12.9

File hashes

Hashes for snappylapy-0.6.1-py3-none-any.whl
Algorithm Hash digest
SHA256 cef5022af1c7c229e25dbe62c6557f480031ed420d64c39c308d26bf11dd782a
MD5 328ebb85baa3f96e8542252a4068eb23
BLAKE2b-256 1b800590b8ba6d17fde35a62399e63eee3802e51fcd786a7687c8c65e572de8a

See more details on using hashes here.

Provenance

The following attestation bundles were made for snappylapy-0.6.1-py3-none-any.whl:

Publisher: release.yaml on martinmoldrup/snappylapy

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