Pytest: как разделить состояние базы данных между тестами - PullRequest
1 голос
/ 18 июня 2019

Контекст

У меня есть следующая схема тестирования:

@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()

Где test_step_2 зависит от test_step_1, а test_step_2 зависит от изменений базы данных, произошедших в test_step_1.

Вопрос

Как разделить состояние БД между test_step_1 и test_step_2? @pytest.mark.django_db откатывает состояние базы данных после test_step_1 end, что приводит к неудаче теста.

Пример действительного кода

@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())
...