CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/pypi-syrupy

Pytest snapshot testing utility that enables developers to write tests asserting immutability of computed results.

Overall
score

80%

Overview
Eval results
Files

core-assertions.mddocs/

Core Snapshot Assertions

Primary snapshot assertion functionality providing the main interface for snapshot testing in pytest. The SnapshotAssertion class offers a fluent interface for configuration and supports various assertion patterns.

Capabilities

Basic Snapshot Assertion

Core assertion functionality using equality comparison with automatic snapshot generation and validation.

class SnapshotAssertion:
    def __eq__(self, other: SerializableData) -> bool:
        """
        Compare data against stored snapshot using equality operator.
        
        Parameters:
        - other: Any data to compare against snapshot
        
        Returns:
        bool: True if data matches snapshot, False otherwise
        
        Raises:
        AssertionError: When snapshot doesn't match or doesn't exist
        """

    def __call__(self, *, 
                 diff: Optional[SnapshotIndex] = None,
                 exclude: Optional[PropertyFilter] = None,
                 include: Optional[PropertyFilter] = None,
                 extension_class: Optional[Type[AbstractSyrupyExtension]] = None,
                 matcher: Optional[PropertyMatcher] = None,
                 name: Optional[SnapshotIndex] = None) -> 'SnapshotAssertion':
        """
        Configure snapshot assertion with options.
        
        Parameters:
        - diff: Index for snapshot diff (deprecated)
        - exclude: Function to exclude specific properties
        - include: Function to include specific properties 
        - extension_class: Custom extension class for serialization
        - matcher: Function to transform values during comparison
        - name: Specific name for the snapshot
        
        Returns:
        SnapshotAssertion: Configured assertion instance for chaining
        """

Usage examples:

def test_basic_assertion(snapshot):
    # Simple equality assertion - creates snapshot on first run
    actual = {"name": "Alice", "age": 30}
    assert actual == snapshot

def test_configured_assertion(snapshot):
    from syrupy.matchers import path_type
    
    data = {"timestamp": "2023-12-01", "value": 42}
    
    # Configure with matcher to handle dynamic timestamp
    assert data == snapshot(matcher=path_type({
        "timestamp": (str, "<timestamp>")
    }))

def test_multiple_snapshots(snapshot):
    # Multiple snapshots in one test - automatically indexed
    assert "first result" == snapshot
    assert "second result" == snapshot
    assert {"data": "third"} == snapshot

Extension Configuration

Methods for configuring custom serialization extensions and setting default behaviors.

def use_extension(self, extension_class: Type[AbstractSyrupyExtension]) -> 'SnapshotAssertion':
    """
    Configure snapshot to use specific extension.
    
    Parameters:
    - extension_class: Extension class for custom serialization
    
    Returns:
    SnapshotAssertion: New instance with specified extension
    """

def with_defaults(self, **kwargs) -> 'SnapshotAssertion':
    """
    Create snapshot assertion with default configuration.
    
    Parameters:
    - **kwargs: Default options (matcher, include, exclude, extension_class)
    
    Returns:
    SnapshotAssertion: New instance with default configuration
    """

Usage examples:

def test_json_extension(snapshot):
    from syrupy.extensions.json import JSONSnapshotExtension
    
    data = {"users": [{"id": 1, "name": "Alice"}]}
    
    # Use JSON extension for clean JSON output
    assert data == snapshot.use_extension(JSONSnapshotExtension)

def test_image_snapshot(snapshot):
    from syrupy.extensions.image import PNGImageSnapshotExtension
    
    # Binary image data
    image_bytes = b"\\x89PNG\\r\\n\\x1a\\n..."
    
    assert image_bytes == snapshot.use_extension(PNGImageSnapshotExtension)

def test_default_config(snapshot):
    from syrupy.filters import props
    
    # Create snapshot with default exclusions
    configured_snapshot = snapshot.with_defaults(
        exclude=props("private_field", "internal_data")
    )
    
    data = {
        "public": "visible", 
        "private_field": "hidden",
        "internal_data": "secret"
    }
    
    assert data == configured_snapshot

Assertion Result Handling

Internal result handling and metadata access for assertion outcomes.

class AssertionResult:
    def __init__(self,
                 snapshot_location: str,
                 snapshot_name: str,
                 success: bool = False,
                 assertion_success: bool = False,
                 recalled_data: SerializedData = "",
                 snapshot_data: SerializedData = "",
                 exception: Exception = None):
        """
        Result of snapshot assertion operation.
        
        Parameters:
        - snapshot_location: File path of snapshot
        - snapshot_name: Name identifier for snapshot
        - success: Whether snapshot operation succeeded
        - assertion_success: Whether assertion passed
        - recalled_data: Data retrieved from snapshot
        - snapshot_data: Data being compared
        - exception: Any exception that occurred
        """

def assert_match(self, data: Any) -> AssertionResult:
    """
    Perform snapshot assertion and return detailed result.
    
    Parameters:
    - data: Data to compare against snapshot
    
    Returns:
    AssertionResult: Detailed assertion outcome
    """

@property
def num_executions(self) -> int:
    """
    Number of times this snapshot assertion has been executed.
    
    Returns:
    int: Execution count
    """

@property  
def executions(self) -> Dict[int, AssertionResult]:
    """
    Dictionary of execution results indexed by execution number.
    
    Returns:
    Dict[int, AssertionResult]: Mapping of execution index to results
    """

@property
def index(self) -> SnapshotIndex:
    """
    Current snapshot index (auto-incremented or custom name).
    
    Returns:
    SnapshotIndex: Current snapshot identifier
    """

@property
def name(self) -> str:
    """
    Name of the current snapshot for file storage.
    
    Returns:
    str: Snapshot name used in file system
    """

Diff Mode Configuration

Control how snapshot differences are displayed when assertions fail.

class DiffMode(Enum):
    DETAILED = "detailed"    # Show full diff with context
    DISABLED = "disabled"    # Disable diff display

def get_assert_diff(self, diff_mode: DiffMode = DiffMode.DETAILED) -> List[str]:
    """
    Generate diff representation for assertion failure.
    
    Parameters:
    - diff_mode: How to display differences
    
    Returns:
    List[str]: Lines of diff output for display
    """

Usage with CLI:

# Enable detailed diffs (default)
pytest --snapshot-diff-mode=detailed

# Disable diffs for performance with large snapshots  
pytest --snapshot-diff-mode=disabled

Install with Tessl CLI

npx tessl i tessl/pypi-syrupy

docs

cli-integration.md

core-assertions.md

extensions.md

filters.md

index.md

matchers.md

tile.json