You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
My project uses django_audit_log. When pytest creates the test database it fails because whilst creating it and applying migrations it generates models. These trigger the auditlog, whose own latest migrations have not yet been applied, which attempts to insert an audit record. This fails due to a database schema mismatch with the audit log model.
To avoid the issue I would like to override the django_db_setup fixture, something akin to the following:
@pytest.fixture(scope="session")defdjango_db_setup(django_db_setup):
fromauditlog.contextimportdisable_auditlogwithdisable_auditlog():
# Invoke the db_setup logic here...
The issue of course is that by the time the overriding fixture is called, the overridden one has already been executed. The examples at https://docs.pytest.org/en/7.1.x/how-to/fixtures.html#overriding-fixtures-on-various-levels show various means of overriding fixtures but they are all fairly trivial, there are no examples where the fixture does something relatively heavyweight.
I don't want to copy/paste the logic of django_db_setup and amend as that will likely lead to issues if the code changes in future.
To ease this, would you consider splitting "complex" fixtures such as this into two parts? The fixture and an implementing function, the fixture simply delegating to the function? The fixture should also be documented as simply delegating to the defined function.
This would allow users to override just the fixture, but reuse the implementation.
The implementation itself can't be a fixture as the same issue arises. If it's passed as a dependency then it's already executed by the time the overriding fixture is invoked.
One alternative is to have a delegate fixture that returns a function that invokes the original fixture, wrapping with whatever logic is desired. The issue here is that pytest checks for direct calls and rejects them. This of course can be worked around by poking inside the wrapped object, but that too is a little 'ick'.
E.g.
@pytest.fixture(scope="session")defdjango_db_setup(db_setup_delegate):
db_setup_delegate()
@pytest.fixture(scope="session")defdb_setup_delegate(request, django_test_environment, \
django_db_blocker, django_db_use_migrations, \
django_db_keepdb, django_db_createdb, django_db_modify_db_settings):
defdo_setup():
fromauditlog.contextimportdisable_auditlogwithdisable_auditlog():
frompytest_django.fixturesimportdjango_db_setupasdbs# This fails if called on dbs directlynext(dbs.__pytest_wrapped__.obj(
request,
django_test_environment,
django_db_blocker,
django_db_use_migrations,
django_db_keepdb,
django_db_createdb,
django_db_modify_db_settings)
)
returndo_setup
Thoughts? Is there an easy solution I've missed?
Thanks
The text was updated successfully, but these errors were encountered:
My project uses django_audit_log. When pytest creates the test database it fails because whilst creating it and applying migrations it generates models. These trigger the auditlog, whose own latest migrations have not yet been applied, which attempts to insert an audit record. This fails due to a database schema mismatch with the audit log model.
To avoid the issue I would like to override the
django_db_setup
fixture, something akin to the following:The issue of course is that by the time the overriding fixture is called, the overridden one has already been executed. The examples at https://docs.pytest.org/en/7.1.x/how-to/fixtures.html#overriding-fixtures-on-various-levels show various means of overriding fixtures but they are all fairly trivial, there are no examples where the fixture does something relatively heavyweight.
I don't want to copy/paste the logic of
django_db_setup
and amend as that will likely lead to issues if the code changes in future.To ease this, would you consider splitting "complex" fixtures such as this into two parts? The fixture and an implementing function, the fixture simply delegating to the function? The fixture should also be documented as simply delegating to the defined function.
This would allow users to override just the fixture, but reuse the implementation.
The implementation itself can't be a fixture as the same issue arises. If it's passed as a dependency then it's already executed by the time the overriding fixture is invoked.
One alternative is to have a delegate fixture that returns a function that invokes the original fixture, wrapping with whatever logic is desired. The issue here is that pytest checks for direct calls and rejects them. This of course can be worked around by poking inside the wrapped object, but that too is a little 'ick'.
E.g.
Thoughts? Is there an easy solution I've missed?
Thanks
The text was updated successfully, but these errors were encountered: