2

I create the message instance in a fixture with scope='module', right in the test file. But when the test reaches another module, this message instance still exists in the database.

in .../apps/dialogs/test/api/test_message.py

@pytest.fixture(scope='module')
def message_by_auth_user(django_db_setup, django_db_blocker,
                         message_factory: type,
                         user_factory: type,
                         user_with_auth: User) -> Message:
    """Return message by auth user."""
    with django_db_blocker.unblock():
        message = message_factory(written_by=user_with_auth)  # Message object (1)
        message_text = message.message  # 'text_message_№_1'
        return message

in .../apps/users/test/api/test_users.py


@pytest.mark.django_db
def test_get_users_view_with_filter(bool_value: bool,
                                    user_count_change: int,
                                    filter_pattern: str,
                                    api_auth_client: APIClient,
                                    user_with_auth: User,
                                    user_factory: type):
    message_count = Message.objects.all().count()  # 1
    message = Message.objects.first()  # Message object (1)
    message_text = message.message # 'text_message_№_1'

UPDATE

After I replaced the 'return' with a 'yield', and after the 'yield' I manually deleted the object, everything works correctly. But shouldn't the test do it automatically, as it does in my other fixtures? For example, if scope = 'function' then the test automatically deletes the object (after each test), without any 'yield'

If the message instance is not manually deleted, it will exist throughout the entire session, even if scope='module'. Why is this happening???

@pytest.fixture(scope='module')
def message_by_auth_user(django_db_setup, django_db_blocker,
                         message_factory: type,
                         user_factory: type,
                         user_with_auth: User) -> Message:
    """Return message by auth user."""
    with django_db_blocker.unblock():
        message = message_factory(written_by=user_with_auth)
        yield message
        message.delete()  # This code is executed when fixture run teardown, after testing current module
  • 1
    Your fixture creates the object, but does not delete it after usage, as far as I can see - so it will just remain. – MrBean Bremen Aug 16 '20 at 18:04
  • @MrBeanBremen yes, but why does function scope fixtures delete it **automatically** after each test? (check **UPDATE** above) I **expect** module scope fixture to have the **same** behavior after each test module. – Максим прокулус Aug 17 '20 at 11:49
  • Your fix is the correct way to do this. As for the function scope behavior - I'm not sure. Are you saying that if you use the same fixture with a function scope, without using any other db-related fixtures, it will reset the db after each test? – MrBean Bremen Aug 17 '20 at 17:45
  • @MrBeanBremen Exactly!!! In the first section of the code(with 'return'), if i'l put scope = 'function', then the instance will be deleted after each test automatically. – Максим прокулус Aug 17 '20 at 18:20
  • 1
    Well, my best guess is that there is some other function-scope fixture involved that resets the database to the initial state after the test. This would not reset changes that have been made before the fixture is involved (e.g. changes made in module- or session-bases fixtures). Maybe `@pytest.mark.django_db` even does that - I haven't used that. – MrBean Bremen Aug 17 '20 at 18:29

0 Answers0