简体   繁体   English

如何使用 pytest-django 测试非托管模型

[英]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.在我的 django 项目中,我有 5 个应用程序,共有 15 个模型,它们都是非托管的。 I've written some tests in pytest-django, and when I run them, they fail due to not being able to find tables.我在 pytest-django 中编写了一些测试,当我运行它们时,由于无法找到表而失败。

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.我试图让它在Django==4.0.4pytest-django==4.5.2上工作,但我在那里找到的结果都没有对我有用。 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.认为我们可以通过覆盖django_db_setup来实现我们需要的东西似乎很直观,这就是其他答案中提供的解决方案。 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文档的摘录:

pytest-django calls django.setup() automatically. pytest-django 自动调用 django.setup() 。 If you want to do anything before this, you have to create a pytest plugin and use the pytest_load_initial_conftests() hook如果你想在此之前做任何事情,你必须创建一个 pytest 插件并使用 pytest_load_initial_conftests() 钩子

Read more 阅读更多

You can override the django_db_setup fixture in conftest.py file:您可以覆盖conftest.py文件中的django_db_setup夹具:

@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.这将在运行测试之前为非托管模型创建表,并在测试后删除这些表。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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