Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PoC for using load_database by pytest-postgresql #721

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions newsfragments/721.misc.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
For postgresql tests use the ability of pytest-postgresql to create database
and fill in it's contents once per full test runs.

This ought to speed up the full test suite as instead of creating database
and filling up with test data each test it'll be done only once,
and each tests postgresql will clone the template database with data
into a test database.
42 changes: 35 additions & 7 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from zope.sqlalchemy import register

from pytest_pyramid import factories
from pytest_postgresql.factories import postgresql_proc as posgresql_proc_factory
import pyramid_basemodel


Expand All @@ -30,11 +31,38 @@
return request


def load_database(**kwargs):
"""Pre-load database with data and structure."""
from pyramid_fullauth.models import Base, Group # pylint:disable=import-outside-toplevel

Check warning on line 36 in tests/conftest.py

View check run for this annotation

Codecov / codecov/patch

tests/conftest.py#L36

Added line #L36 was not covered by tests

connection = f"postgresql+psycopg://{kwargs['user']}:@{kwargs['host']}:{kwargs['port']}/{kwargs['dbname']}"
engine = create_engine(connection)
Base.metadata.create_all(engine)
session = scoped_session(sessionmaker())
session.configure(bind=engine)

Check warning on line 42 in tests/conftest.py

View check run for this annotation

Codecov / codecov/patch

tests/conftest.py#L38-L42

Added lines #L38 - L42 were not covered by tests
# This group will always be present in each test even though after each test the test database is dropped.
# That's because it lives in temporary database which
# for postgresql based tests is used to recreate a test database.
session.add(

Check warning on line 46 in tests/conftest.py

View check run for this annotation

Codecov / codecov/patch

tests/conftest.py#L46

Added line #L46 was not covered by tests
Group(
name="Added in pre-init stage",
)
)
session.commit()

Check warning on line 51 in tests/conftest.py

View check run for this annotation

Codecov / codecov/patch

tests/conftest.py#L51

Added line #L51 was not covered by tests


# Createa a process fixture referencing the load_database
postgresql_proc = posgresql_proc_factory(
load=[load_database],
)


@pytest.fixture(scope="function", params=["sqlite", "mysql", "postgresql"])
def db_session(request):
"""Session for SQLAlchemy."""
from pyramid_fullauth.models import Base # pylint:disable=import-outside-toplevel

connection = ""
if request.param == "sqlite":
connection = "sqlite:///fullauth.sqlite"
elif request.param == "mysql":
Expand All @@ -47,15 +75,15 @@
engine = create_engine(connection, echo=False, poolclass=NullPool)
pyramid_basemodel.Session = scoped_session(sessionmaker())
register(pyramid_basemodel.Session)
pyramid_basemodel.bind_engine(engine, pyramid_basemodel.Session, should_create=True, should_drop=True)
if request.param == "postgresql":
pyramid_basemodel.bind_engine(engine, pyramid_basemodel.Session, should_create=False, should_drop=False)

Check warning on line 79 in tests/conftest.py

View check run for this annotation

Codecov / codecov/patch

tests/conftest.py#L79

Added line #L79 was not covered by tests
else:
pyramid_basemodel.bind_engine(engine, pyramid_basemodel.Session, should_create=True, should_drop=True)

def destroy():
transaction.commit()
Base.metadata.drop_all(engine)
yield pyramid_basemodel.Session

request.addfinalizer(destroy)

return pyramid_basemodel.Session
transaction.commit()
Base.metadata.drop_all(engine)


@pytest.fixture
Expand Down
Loading