syrusakbary / snapshottest

Snapshot Testing utils for Python 📸
MIT License
537 stars 102 forks source link

pytest --snapshot-update not working #53

Open wilk opened 6 years ago

wilk commented 6 years ago

Hi,

I'm doing TDD to implement e2e in Django with Graphene. When I run pytest I got my snapshots obsolete and I need to update them. So, following the suggestion, I re-run pytest with the option --snapshot-update but it's simply not working. I then need to remove all the snapshots and then re-run pytest, checking if the snapshots are correct.

I'm working with:

demeralde commented 6 years ago

I have the same issue. Any luck figuring out a solution?

thomasrstorey commented 6 years ago

I also have this problem, for what it's worth. I'll do some investigating if I find some time.

thomasrstorey commented 6 years ago

Ok I figured out how to do it for my use case, hopefully this helps someone else too. I am using a unittest.TestCase style test suite with pytest as my runner. It seems that snapshottest.TestCase that extends from unittest.TestCase does not support --snapshot-update directly, presumably because it relies on the given test runner to provide the parsing of the --snapshot-update argument and act accordingly. Unfortunately the snapshot pytest fixture is yield style, and so is not compatible with unittest.TestCase style tests, because they cannot receive arguments from fixtures. The solution is to add an intermediate fixture that will assign an instance property to the unittest.TestCase instance that provides access to the snapshot fixture, which is able to access the command line args provided to the snapshottest pytest plugin. Put this in a conftest.py file in the root of your tests directory:

import pytest
from snapshottest.pytest import PyTestSnapshotTest

@pytest.fixture(scope="class")
def mysnapshot(request):
    """
    Wraps snapshot fixture to provide instance snapshot property for
    unittest.TestCase tests
    """
    request.cls.snapshot = PyTestSnapshotTest(request)

Then add the pytest.mark.usefixtures decorator on your unittest.TestCase class. This will use the fixture you defined to add a snapshot property to the instance.

import pytest
from unittest import TestCase

@pytest.mark.usefixtures('mysnapshot')
class MyTestCase(TestCase):
    def test_foo(self):
        assert hasattr(self, 'snapshot')