Pytest snapshot testing utility that enables developers to write tests asserting immutability of computed results.
Overall
score
80%
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.
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"} == snapshotMethods 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_snapshotInternal 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
"""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=disabledInstall with Tessl CLI
npx tessl i tessl/pypi-syrupyevals
scenario-1
scenario-2
scenario-3
scenario-4
scenario-5
scenario-6
scenario-7
scenario-8
scenario-9
scenario-10