Pytest: how to share database state between tests

Viewed 848

Context

I have following test schema:

@pytest.mark.django_db
class TestScenario:

    @pytest.mark.dependency()
    def test_step_1():
        database_mutations()
        asserts()

    @pytest.mark.dependency(depends=['TestScenario::test_step_1'])
    def test_step_2():
        actions_which_depend_on_test_step_1_database_mutations()
        asserts()

Where test_step_2 depends on test_step_1, and test_step_2 relies on database changes that occurred in test_step_1.

Question

How do i share db state between test_step_1 and test_step_2? @pytest.mark.django_db rolls back database state after test_step_1 end which cause test fail.

Actual code example

@pytest.mark.django_db
class TestImpulseMachine:

    cls_name = 'TestImpulseMachine'

    # Workaround to share one test result for another.
    # This is what i want to avoid.
    @pytest.fixture
    def _test_contacts_create(self, authed_api_client, impulse_machine):
        return authed_api_client.post(
            '/api/v2/contacts/', {'machine': impulse_machine.pk})

    @pytest.mark.dependency()
    def test_contacts_create(
        # Given.
        self, snapshot,
        # When:
        _test_contacts_create,
    ):
        # Then:
        assert _test_contacts_create.status_code == 201
        snapshot.assert_match(_test_contacts_create.json())

    @pytest.mark.dependency(depends=[f'{cls_name}::test_contacts_create'])
    def test_orders_patch_for_amount_and_cryptogram_and_cardholder(
        # Given.
        self, authed_api_client, cryptogram, snapshot, mocker,
        # This is what i want to avoid.
        _test_contacts_create,
    ):
        start_cryptogram_payment_mock = mocker.patch.object(
            models.Order, 'start_cryptogram_payment', return_value=True)
        order = models.Order.objects.get()
        # When:
        res = authed_api_client.patch(
            f'/api/v2/orders/{order.pk}/',
            {'amount': 10, 'cryptogram': cryptogram, 'cardholder': 'autotest'},
            format='json')
        # Then:
        assert res.status_code == 200
        start_cryptogram_payment_mock.assert_called_once()
        snapshot.assert_match(res.json())
0 Answers
Related