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

cli-integration.mddocs/

CLI Integration

Comprehensive pytest integration providing command-line options, session management, and reporting capabilities. Syrupy automatically registers as a pytest plugin and provides both CLI options and pytest fixtures for snapshot testing workflows.

Capabilities

Command-Line Options

Syrupy adds several command-line options to pytest for controlling snapshot behavior, reporting, and configuration.

def pytest_addoption(parser: "pytest.Parser") -> None:
    """
    Register syrupy command-line options with pytest.
    
    Adds options to pytest's argument parser for snapshot configuration,
    update modes, reporting, and extension selection.
    """

Core Options

Essential options for snapshot update workflows and basic configuration.

# Update snapshots to match current test assertions
pytest --snapshot-update

# Show detailed information about snapshot operations
pytest --snapshot-details

# Warn about unused snapshots instead of failing tests
pytest --snapshot-warn-unused

# Disable colored output in test results
pytest --snapshot-no-colors

Usage examples:

# Standard workflow: run tests and update failing snapshots
pytest tests/
pytest --snapshot-update  # Update snapshots after reviewing failures

# Generate detailed report with snapshot file locations
pytest --snapshot-details tests/

# CI/CD friendly: don't fail on unused snapshots, just warn
pytest --snapshot-warn-unused tests/

# Terminal-friendly: disable colors for log processing
pytest --snapshot-no-colors tests/ > test_results.log

Advanced Configuration

Options for customizing snapshot behavior, extensions, and diff display.

# Use custom extension class by default
pytest --snapshot-default-extension=syrupy.extensions.json.JSONSnapshotExtension

# Control diff display mode for performance
pytest --snapshot-diff-mode=detailed  # Show full diffs (default)
pytest --snapshot-diff-mode=disabled  # Disable diffs for large snapshots

# Ignore specific file extensions during snapshot discovery
pytest --snapshot-ignore-file-extensions=.tmp,.cache

# Enable PyCharm diff integration
pytest --snapshot-patch-pycharm-diff

Usage examples:

# Use JSON extension for all snapshots in a test run
pytest --snapshot-default-extension=syrupy.extensions.json.JSONSnapshotExtension tests/api/

# Optimize performance for tests with large snapshots
pytest --snapshot-diff-mode=disabled tests/integration/

# Ignore temporary and cache files when checking for unused snapshots
pytest --snapshot-ignore-file-extensions=.tmp,.cache,.bak tests/

# IDE integration for better diff viewing
pytest --snapshot-patch-pycharm-diff tests/

Session Management

Internal pytest hooks managing snapshot session lifecycle, test collection, and reporting.

def pytest_sessionstart(session: Any) -> None:
    """Initialize snapshot session before tests are collected and run."""

def pytest_collection_modifyitems(session: Any, config: Any, items: List["pytest.Item"]) -> None:
    """Process collected test items after collection."""

def pytest_collection_finish(session: Any) -> None:
    """Finalize test collection and select snapshot-related items."""

def pytest_runtest_logreport(report: pytest.TestReport) -> None:
    """Handle test run reports during setup, call, and teardown phases."""

def pytest_sessionfinish(session: "pytest.Session", exitstatus: int) -> None:
    """Finalize snapshot session and set appropriate exit status."""

def pytest_terminal_summary(terminalreporter: Any, exitstatus: int, config: Any) -> None:
    """Add syrupy-specific summary to pytest terminal output."""

Snapshot Fixture

Primary pytest fixture providing the snapshot assertion interface to test functions.

@pytest.fixture
def snapshot(request: "pytest.FixtureRequest") -> "SnapshotAssertion":
    """
    Pytest fixture providing snapshot assertion capability.
    
    Parameters:
    - request: Pytest fixture request containing configuration and test context
    
    Returns:
    SnapshotAssertion: Configured snapshot assertion instance
    
    The fixture automatically configures based on CLI options:
    - update_snapshots: From --snapshot-update flag
    - extension_class: From --snapshot-default-extension option  
    - test_location: Derived from pytest test node
    - session: Active snapshot session
    """

Usage examples:

def test_basic_fixture(snapshot):
    """Standard fixture usage"""
    result = {"message": "Hello world"}
    assert result == snapshot

def test_fixture_configuration(snapshot):
    """Fixture respects CLI configuration"""
    # If run with --snapshot-default-extension=syrupy.extensions.json.JSONSnapshotExtension
    # this will automatically use JSON extension
    data = {"users": [{"name": "Alice"}]}
    assert data == snapshot

def test_multiple_snapshots(snapshot):
    """Fixture supports multiple snapshots per test"""
    assert "first snapshot" == snapshot
    assert {"second": "snapshot"} == snapshot
    assert ["third", "snapshot"] == snapshot

# Session-scoped IDE integration fixture
@pytest.fixture(scope="session", autouse=True)
def _syrupy_apply_ide_patches(request: "pytest.FixtureRequest") -> Iterator[None]:
    """
    Automatic fixture for IDE integration patches.
    
    Applies when --snapshot-patch-pycharm-diff is enabled.
    """

Assertion Representation

Custom assertion failure messages and diff display for snapshot comparisons.

def pytest_assertrepr_compare(config: "pytest.Config", op: str, left: Any, right: Any) -> Optional[List[str]]:
    """
    Provide custom assertion representation for snapshot comparisons.
    
    Parameters:
    - config: Pytest configuration with syrupy options
    - op: Comparison operator (typically "==")
    - left: Left side of comparison (often SnapshotAssertion)
    - right: Right side of comparison (test data)
    
    Returns:
    Optional[List[str]]: Custom assertion failure message lines
    """

Example assertion output:

def test_failing_snapshot(snapshot):
    actual = {"name": "Bob", "age": 25}
    assert actual == snapshot
    
# When snapshot contains {"name": "Alice", "age": 30}, output shows:
# 
# >       assert actual == snapshot
# E       AssertionError: assert {'age': 25, 'name': 'Bob'} == snapshot_name
# E         [- snapshot_name] [+ received]
# E         {
# E         - 'age': 30,
# E         + 'age': 25,
# E         - 'name': 'Alice',
# E         + 'name': 'Bob',
# E         }

Exit Status Handling

Syrupy modifies pytest exit status based on snapshot-specific conditions.

EXIT_STATUS_FAIL_UNUSED = 1  # Exit code when unused snapshots found

Exit status behavior:

# Normal test failures: exit code from pytest
pytest tests/  # Exit 1 if tests fail, 0 if pass

# Unused snapshots found: exit code 1 (unless --snapshot-warn-unused)
pytest tests/  # Exit 1 if unused snapshots exist

# With warning mode: exit code 0 even with unused snapshots
pytest --snapshot-warn-unused tests/  # Exit 0, just warns about unused

# Update mode: cleans up unused snapshots
pytest --snapshot-update tests/  # Removes unused snapshots, exit 0 if successful

Environment Variables

Environment variables that affect syrupy behavior:

DISABLE_COLOR_ENV_VAR = "ANSI_COLORS_DISABLED"  # Disable colored output
# Alternative: NO_COLOR environment variable also disables colors

Usage examples:

# Disable colors via environment variable
export ANSI_COLORS_DISABLED=1
pytest tests/

# Alternative color disabling
export NO_COLOR=1
pytest tests/

# Override in single command
ANSI_COLORS_DISABLED=1 pytest tests/

Integration Examples

Complete examples showing CLI integration in different scenarios:

# Development workflow
pytest tests/test_api.py                    # Run tests, see failures
pytest --snapshot-update tests/test_api.py # Update snapshots after review

# CI/CD pipeline
pytest --snapshot-warn-unused tests/       # Don't fail on unused snapshots
pytest --snapshot-no-colors tests/ > results.log  # Log-friendly output

# Performance testing with large snapshots  
pytest --snapshot-diff-mode=disabled tests/large_data/

# JSON API testing
pytest --snapshot-default-extension=syrupy.extensions.json.JSONSnapshotExtension tests/api/

# Comprehensive reporting
pytest --snapshot-details --snapshot-warn-unused tests/

# IDE integration
pytest --snapshot-patch-pycharm-diff tests/

# Custom extension with detailed reporting
pytest \
  --snapshot-default-extension=myproject.extensions.CustomExtension \
  --snapshot-details \
  --snapshot-update \
  tests/custom/

Plugin Registration

Syrupy automatically registers as a pytest plugin through setuptools entry points:

# In pyproject.toml
[tool.poetry.plugins.pytest11]
syrupy = 'syrupy'

This enables automatic discovery and loading when syrupy is installed, making all CLI options and fixtures available without additional configuration.

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