python - 一般如何创建仅测试 Django 模型(特别是使用 pytest-django)

标签 python django pytest abstract-class pytest-django

一般问题: 我有一个抽象模型,我想用一个真实的模型实例来测试,但是我不想完全重构我的项目/测试格式。引用这两个答案:First answer Second answer

我要 A) 在每个测试应用文件夹中定义模型,而不是在实际应用中定义它们 B) 每个测试文件夹没有额外/单独的 apps.py 和 settings.py 配置。 我知道这是可能的,因为 django 项目有一个非常相似的 test structure像这样,但他们使用 test run script我无法完全破译。

test/文件夹反射(reflect)了我的应用程序结构(即 blog/、projects/、richeditable/)。

backend
├── projects
├── blog
├── richeditable
├── tests
│   ├── __init__.py
│   ├── conftest.py
│   ├── blog
│   │   ├── ...
│   ├── projects
│   │   ├── ...
│   └── richeditable
│   │   ├── __init__.py
│   │   ├── test_model.py
│   │   ├── models.py         <-------------- This defines a model that inherits from richeditable.models
# richeditable/models.py
class Draftable(models.Model):
    blah = models.IntegerField()

    class Meta:
        abstract = True
# tests/richeditable/models.py
class DummyDraftable(Draftable):
    additional_field = models.BooleanField()

#   class Meta:
#       app_label = "some_app" 
#  ^--- Django does not seem to like having this blank and I don't know what to put to make this work
# tests/richeditable/test_model.py
import pytest

@pytest.fixture
def add_app(settings):
    settings.INSTALLED_APPS += ['backend.tests.richeditable']
    
# presumably the above fixture would affect the apps/models
# settings before the database is created, but that does not seems to be the case
def test_please_work(add_app, db):
    assert DummyDraftable.objects.create(blah=1, additional_field=True) is not None

根据我所看到的关于 django project script 的最佳猜测是它们作为模块加载到每个文件夹中进行测试,并在测试用例之前的运行时将其添加到 INSTALLED_APPS。但是,您不能只是简单地更改 INSTALLED_APPS,因为正在添加模型并且必须事先对测试数据库进行迁移,而且似乎需要定义一个 AppConfig (因为如果你不这样做,Django 就会失去理智)。我试图为模型包含 app_label 元字段,但它没有用,或者我可能做错了什么。但重点是,我没有看到脚本创建 AppConfig 并且他们不必在他们的模型中声明 Meta。 py


Pytest 特定内容: pytest-django 使事情变得更加复杂,因为它不使用 Django 的 TestRunner 接口(interface)。这是 how you would do it如果是这样(请注意操作顺序)。我已经尝试在使用关联的固定装置实例化数据库之前修改 settings pytest 固定装置,但是无论我做什么,这都不会最终加载模块。来自 looking at the source code ,似乎设置已根据 settings.py 指定的内容固定到位,并且修改 settings fixture 对应用程序加载没有影响。


最佳答案

所以我最终解决了我自己的问题。正如@hoefling 提到的,最好的方法是创建一个单独的设置文件来扩展您的普通设置文件,并将其指定为您的 pytest 设置文件。

// pytest.ini
[pytest]
addopts = --ds=config.settings.test

需要注意的重要一点是,正如我发现的那样,您不能让测试模块与现有应用同名。因此,无论您做什么,都不允许使用 backend/tests/richeditable 的结构。所以我在每个文件夹前加上 test_ 并且它工作正常。这也解决了必须在模型中包含 app_label 的问题。

# testsettings.py
from .settings import *  # noqa

INSTALLED_APPS += [
    'backend.tests.test_projects',
    'backend.tests.test_blog',
    'backend.tests.test_richeditable',
]
backend
├── projects
├── blog
├── richeditable
├── tests
│   ├── __init__.py
│   ├── conftest.py
│   ├── test_blog
│   │   ├── ...
│   ├── test_projects
│   │   ├── ...
│   └── test_richeditable
│   │   ├── __init__.py
│   │   ├── test_model.py
│   │   ├── models.py  

关于python - 一般如何创建仅测试 Django 模型(特别是使用 pytest-django),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70637784/

相关文章:

python - django 的 gentelella 无法识别 custom.css 上的更改

python - 使用 py.test,数据库不会在 LiveServerTestCase 之后重置

python - 如何访问pytest中的整体运行时?

python - 是否可以将经过训练的 CNN 存储为 .mat 文件并使用该文件在 Python 中制定分类算法?

python - 具有 "gcloud functions deploy"的 GCP 云函数失败,--source 作为文件而不是目录

python - 你如何在 Python/Django/MySQL 中避免这种竞争条件?

Django Rest Framework 方法\"GET\"不允许错误?

python - 不能将 attach_mock 与 autospec 函数模拟一起使用

python - 组合两列给出 ValueError : Wrong number of items passed 2, placement implies 1

python - 按组计算百分位数,然后添加到现有数据框