I am trying to have pytest setup a test database automatically based on whether it runs locally or on our CI server. Please see below the code. For this I created a CLI option.
When this option is passed I want pytest-postgresql to use the postgresql_noproc_factory
(GitHub README). So I created a fixture that selects the factory to be used. However, if I understand correctly, this creates a "fixture of a fixture" so when it is injected into setup_database
it doesn't work and gives an error message:
def dbcreator():
> return postgresql_my.cursor().connection
E AttributeError: 'function' object has no attribute 'cursor'
Do you possibly know how this could be done with pytest? How do I make pytest instantiate the nested fixture so that it configures the right PostgreSQL engine?
import os
import tempfile
from psycopg2.extensions import connection
import pytest
from pytest_postgresql import factories
from sqlalchemy import create_engine
from sqlalchemy.engine import Engine
def pytest_addoption(parser):
parser.addoption(
"--remote-psql", action="store_true", help="Run it in environment where PSQL runs on network."
)
@pytest.fixture(scope="session")
def cmdopt_remote_psql(request):
return request.config.getoption("--remote-psql")
# Using the postgresql factories to create a postgresql fixture instance
socket_dir = tempfile.TemporaryDirectory()
postgresql_proc_factory = factories.postgresql_proc(port=None, unixsocketdir=socket_dir.name)
postgresql_noproc_factory = factories.postgresql_noproc()
@pytest.fixture(scope="session")
def postgresql_my(cmdopt_remote_psql):
if cmdopt_remote_psql:
return factories.postgresql("postgresql_noproc_factory")
else:
return factories.postgresql("postgresql_proc_factory")
@pytest.fixture(scope="function", autouse=True)
def setup_database(postgresql_my: connection) -> Engine:
"""
See https://medium.com/@geoffreykoh/fun-with-fixtures-for-database-applications-8253eaf1a6d
"""
def dbcreator():
return postgresql_my.cursor().connection
engine = create_engine("postgresql+psycopg2://", creator=dbcreator)
return engine
Aucun commentaire:
Enregistrer un commentaire