Closed xyshell closed 4 days ago
No that's not currently supported. It's create odd dependency issues off the top of my head. I.e. when updating a snapshot, which test case is the source of truth?
No that's not currently supported. It's create odd dependency issues off the top of my head. I.e. when updating a snapshot, which test case is the source of truth?
Hey @noahnu. Thanks for giving it a thought. How about having a fixture to define the single source of truth?, like:
@pytest.fixture
def special_snapshot():
return ...
Then both tests can reference to the fixture, like:
def test1(special_snapshot): # instead of the normal "snapshot"
result = compute(flavor='a')
assert res == special_snapshot
def test2(special_snapshot): # instead of the normal "snapshot"
result = compute(flavor='b')
assert result == special_snapshot
When updating snapshot, there could be some logic to make sure all tests referencing the special_snapshot
producing the same result and got updated together. Does this make sense to you? Happy to discuss more.
Is the issue you're trying to solve that you want to avoid duplicate snapshots in the filesystem? Otherwise I'd probably just do something like:
@pytest.fixture(scope="module")
def some_computation():
return compute(flavor="a")
def test1(some_computation, snapshot):
assert some_computation == snapshot
def test2(some_computation):
assert some_computation == compute(flavor="b")
The scope=module will ensure it's the same value between the 2 test cases. Only 1 test case would have the snapshot but you'd transitively get equality between all values.
To do this entirely in syrupy, I suppose you could hook into the default syrupy extension class (amber) and use the relevant methods to manually recall the snapshot data based on the name of the other function. I don't think this would be simple though.
We might be able to hack something together by patching the SnapshotAssertion class so the test location is optional, or it uses the first node it comes across, e.g.:
import pytest
from syrupy.assertion import SnapshotAssertion
COMPUTE_PRODUCES_SAME_VALUE = True
def compute(flavor):
if COMPUTE_PRODUCES_SAME_VALUE:
return "some-static-value"
return f"computed-{flavor}"
@pytest.fixture(scope="module")
def stateful_snapshot(request: "pytest.FixtureRequest"):
snapshot = SnapshotAssertion(
update_snapshots=request.config.option.update_snapshots,
extension_class=...,
test_location=PyTestLocation(request.node), # TODO: What would this node be?
session=request.session.config._syrupy, # type: ignore
)
class StatefulSnapshot:
assertions: int = 0
def __eq__(self, other) -> bool:
self.assertions += 1
if self.assertions == 1:
return snapshot(name="initial") == other
return snapshot(diff="initial") == other
return StatefulSnapshot()
def test1(stateful_snapshot):
assert compute(flavor='a') == stateful_snapshot
def test2(stateful_snapshot):
assert compute(flavor='b') == stateful_snapshot
ultimately I don't think this is feasible
Hey there, thanks for working on this fantastic project! I've been using it both personally and in work.
One question is: Can we reference the snapshot in another test? pseudo-code to illustrate:
for now, I have to combine them together in one test, like:
But this will make one test too long to be good.
Do we have such feature? I can't find it in the doc (but I may miss something).