如何使用 pytest-django 设置 postgres 数据库?

问题描述 投票:0回答:4

我希望 pytest-django 在创建测试数据库时安装 Postgres 扩展。我一直在研究 conftest.py 来尝试让它工作,但我被卡住了。

我的conftest.py位于我的项目的顶层(与manage.py相同的目录),并包含:

from django.db import connection
import pytest_django
@pytest.fixture(scope='session')
def django_db_setup(*args, **kwargs):
    pytest_django.fixtures.django_db_setup(*args, **kwargs)
    cursor = connection.cursor()
    cursor.execute("create extension pg_trgm")

但是当我运行它时,我得到:

_pytest.vendored_packages.pluggy.PluginValidationError: unknown hook 'pytest_django' in plugin <module 'conftest' from '/path/to/my/conftest.py'>
django unit-testing pytest pytest-django
4个回答
8
投票

您可以使用

pre_migrate
信号。例如:

from django.db.models.signals import pre_migrate
from django.apps import apps

def app_pre_migration(sender, app_config, **kwargs):

    cur = connection.cursor()
    cur.execute('CREATE EXTENSION IF NOT EXISTS pg_trgm;')

pre_migrate.connect(app_pre_migration, sender=apps.get_app_config('app'))

我希望这可以帮助你。


1
投票

我一直在尝试完成同样的事情,并且成功了(在

conftest.py
中):

@pytest.fixture(scope="session")
def django_db_setup(django_db_setup, django_db_blocker):
    """Test session DB setup."""
    with django_db_blocker.unblock():
        with connection.cursor() as cursor:
            cursor.execute("CREATE EXTENSION IF NOT EXISTS citext;")

这里的关键是,您必须使用与标准

pytest-django
固定装置相同的名称来命名自定义固定装置,但还要包含默认固定装置作为参数。这是运行标准装置的方式,而不是导入和调用它。我还发现这会失败,除非我运行
django_db_blocker.unblock()


0
投票

另一种解决方案是将扩展添加到 postgres 模板数据库。这意味着使用

CREATE DATABASE
命令创建的所有测试数据库都将具有指定的扩展名:

psql -d template1 -c 'CREATE EXTENSION IF NOT EXISTS pg_trgm;'

现在,每当 pytest 创建测试数据库时,都会在运行迁移之前安装

pg_trgm
扩展。


0
投票

我终于使用

django_test_environment
夹具解决了这个问题。

import pytest
from django.db import connection
from django.db.models.signals import pre_migrate
from django.apps import apps


def _pre_migration(sender, app_config, **kwargs):
    with connection.cursor() as cursor:
        cursor.execute("CREATE EXTENSION IF NOT EXISTS pg_trgm;")


@pytest.fixture(autouse=True, scope="session")
def django_test_environment(django_test_environment):
    pre_migrate.connect(_pre_migration, sender=apps.get_app_config("my_app"))
© www.soinside.com 2019 - 2024. All rights reserved.