简体   繁体   中英

How to test unmanaged models using pytest-django

In my django project, I have 5 applications, with total 15 models,and all of them are unmanaged. I've written some tests in pytest-django, and when I run them, they fail due to not being able to find tables.

How can I create database entries for all these models so that the tests don't fail?

I was trying to get this to work on Django==4.0.4 , pytest-django==4.5.2 and none of the results I could find out there worked for me. This is what I could figure out:

# add this to conftest.py
@pytest.hookimpl(tryfirst=True)
def pytest_runtestloop():
    from django.apps import apps
    unmanaged_models = []
    for app in apps.get_app_configs():
        unmanaged_models += [m for m in app.get_models()
                             if not m._meta.managed]
    for m in unmanaged_models:
        m._meta.managed = True

It seems intuitive to think that we can achieve what we need by overriding django_db_setup , and that is the solution provided in other answers on SO. However I was not able to get this to work, that might have something to do with changes to the order of execution of these fixtures over the years, I am not sure.

Excerpt from the current pytest-django docs:

pytest-django calls django.setup() automatically. If you want to do anything before this, you have to create a pytest plugin and use the pytest_load_initial_conftests() hook

Read more

You can override the django_db_setup fixture in conftest.py file:

@pytest.fixture(scope="session")
def django_db_setup(django_db_blocker):

    with django_db_blocker.unblock():

        from django.apps import apps

        models_list = apps.get_models()
        for model in models_list:
            with connection.schema_editor() as schema_editor:
                schema_editor.create_model(model)

                if model._meta.db_table not in connection.introspection.table_names():
                    raise ValueError(
                        "Table `{table_name}` is missing in test database.".format(
                            table_name=model._meta.db_table
                        )
                    )

        yield

        for model in models_list:
            with connection.schema_editor() as schema_editor:
                schema_editor.delete_model(model)

This will create the tables for unmanaged models before running tests, and delete those tables after test.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM