Загрузка фикстур pytest из отдельного пакета PoetryPython

Программы на Python
Anonymous
Загрузка фикстур pytest из отдельного пакета Poetry

Сообщение Anonymous »

Я пытаюсь переместить некоторую тестовую конфигурацию в общий пакет Poetry, чтобы избежать повторения одних и тех же настроек.
В проекте есть пакет с именем user-service с папкойtests внутри. Внутри этой папки я пытаюсь загрузить приборы

Код: Выделить всё

user-service/tests/conftest.py:
import pytest

from httpx import AsyncClient, ASGITransport
from sqlalchemy.ext.asyncio import AsyncSession

from user_service.main import app
from common.core.database import get_db
from common.tests.db_conf import (  # noqa: F401
anyio_backend,
test_engine,
setup_db,
db_session,
)

pytest_plugins = ["common.tests.db_conf"]

# Setup http client
@pytest.fixture
async def client(db_session: AsyncSession):
async def override_get_db():
yield db_session

app.dependency_overrides[get_db] = override_get_db

async with AsyncClient(
transport=ASGITransport(app=app), base_url="http://users_test"
) as ac:
yield ac

app.dependency_overrides.clear()

как видите, я пытаюсь загрузить приборы из общего проекта.

Код: Выделить всё

common/common/tests/db_conf.py:
import os

import pytest
from sqlalchemy.ext.asyncio import (
AsyncSession,
create_async_engine,
async_sessionmaker,
AsyncEngine,
)
from sqlalchemy import NullPool
from sqlalchemy.engine import URL

from common.models.base import Model

pytest_plugins = ["anyio"]

@pytest.fixture(scope="session")
def anyio_backend():
return "asyncio"

# Setup test database engine
@pytest.fixture(scope="session")
def test_engine():
DATABASE_URL = URL.create(
drivername="postgresql+psycopg",
username=os.getenv("POSTGRES_USER"),
password=os.getenv("POSTGRES_PASSWORD"),
host=os.getenv("POSTGRES_HOST"),
port=os.getenv("POSTGRES_PORT"),
database=os.getenv("POSTGRES_DB"),
)
engine = create_async_engine(DATABASE_URL, poolclass=NullPool)
return engine

# Setup test database
@pytest.fixture(scope="session")
async def setup_db(test_engine: AsyncEngine):
async with test_engine.begin() as conn:
await conn.run_sync(Model.metadata.create_all)

yield

async with test_engine.begin() as conn:
await conn.run_sync(Model.metadata.drop_all)

await test_engine.dispose()

# Setup test database session
@pytest.fixture
async def db_session(test_engine:  AsyncEngine, setup_db):
conn = await test_engine.connect()
transaction = await conn.begin()

test_async_session = async_sessionmaker(
bind=conn,
class_=AsyncSession,
expire_on_commit=False,
join_transaction_mode="create_savepoint",  # data is not really saved in database so that tests are isolated
)

async with test_async_session() as session:
try:
yield session
finally:
await session.close()
await transaction.rollback()
await conn.close()

Вот мой user-service/pyproject.toml, который загружает общий пакет:

Код: Выделить всё

[tool.poetry]
name = "user-service"
version = "0.1.0"
description = ""
authors = ["Misha4231 "]
readme = "README.md"

[tool.poetry.dependencies]
python = "^3.12"
fastapi = "^0.136.1"
ruff = "^0.15.12"
sqlalchemy = "^2.0.49"
pydantic-settings = "^2.14.0"
uvicorn = "^0.46.0"
alembic = "^1.18.4"
psycopg2-binary = "^2.9.12"
asyncpg = "^0.31.0"
structlog = "^25.5.0"
pytest = "^9.0.3"
pytest-asyncio = "^1.3.0"
pytest-mock = "^3.15.1"
httpx = "^0.28.1"
psycopg = "^3.3.3"
anyio = "^4.13.0"
common = "^0.1.1"

[tool.poetry.group.local.dependencies]
common = { path = "../common", develop = true }

[tool.pytest.ini_options]
asyncio_mode = "auto"
testpaths = ["tests"]
pythonpath = ["..", "."]

[build-system]
requires = ["poetry-core"]
build-backend = "poetry.core.masonry.api"

Когда я запускаю тесты с помощью Docker Compose:

Код: Выделить всё

docker-compose -f docker-compose-test.yml run --rm users_test
Для каждого теста я получаю сообщение об ошибке, сообщающее, что db_session не найден.

Код: Выделить всё

E       fixture 'db_session' not found
>       available fixtures: _class_scoped_runner, _function_scoped_runner, _module_scoped_runner, _package_scoped_runner, _session_scoped_runner, anyio_backend, anyio_backend_name, anyio_backend_options, cache, capfd, capfdbinary, caplog, capsys, capsysbinary, capteesys, class_mocker, client, doctest_namespace, event_loop_policy, free_tcp_port, free_tcp_port_factory, free_udp_port, free_udp_port_factory, mocker, module_mocker, monkeypatch, package_mocker, pytestconfig, record_property, record_testsuite_property, record_xml_attribute, recwarn, session_mocker, subtests, tmp_path, tmp_path_factory, tmpdir, tmpdir_factory, unused_tcp_port, unused_tcp_port_factory, unused_udp_port, unused_udp_port_factory
>       use 'pytest --fixtures [testpath]' for help on them.
Как загрузить приборы из другого пакета Poetry?

Вернуться в «Python»