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

Support database access for "session" level fixtures. #243

Open
dan-passaro opened this issue Jun 8, 2015 · 4 comments
Open

Support database access for "session" level fixtures. #243

dan-passaro opened this issue Jun 8, 2015 · 4 comments

Comments

@dan-passaro
Copy link

Our test suite uses a custom TestRunner which has a run_suite method like so:

def run_suite(self, suite, **kwargs):
    call_command('loaddata', 'foo')
    call_command('loaddata', 'bar')
    return super(CustomTestRunner, self).run_suite(suite, **kwargs)

The fixtures it loads are indeed so common it makes sense just to load them for every test case. For example we host multiple Sites off of our app and one of the fixtures loads a subset of those Site objects. Foreign keys to Site exist in almost all our apps so it makes sense to just load a few before the whole suite.

Although in theory I should be able to rename the fixtures to initial_data.json and have them load, that is for whatever strange reason not working. That is when I found there is no way to duct-tape over it in py.test, because the only time db access is allowed is at the function level.

Are there any plans to include a session-level fixture for db access?

@blueyed
Copy link
Contributor

blueyed commented Jun 9, 2015

Which Django version are you using?
IIRC initial_data.json is not being considered with apps that use migration in Django 1.7+.

There seems to be a workaround in a (possibly duplicate issue): #105 (comment)

You could also use a signal via app/management/__init__.py to work around this:

# Handle initial data in Django 1.7+.

from django.db.models import signals
from django.core.management import call_command

def load_initial_data(app_config, sender, **kwargs):
    my_label = __package__.split(".")[-2]
    if sender.label == my_label:
        call_command('loaddata', 'initial_data.yaml', app_label=my_label)

signals.post_migrate.connect(load_initial_data, weak=False)

See also #220 (comment)

@dan-passaro
Copy link
Author

Aha! I had actually tried using _django_db_setup but got errors about not being allowed to access the Django DB without a marker. I suppose the _django_cursor_wrapper suppresses that issue as shown in #105. Thank you for the link @blueyed

It looks like this will allow me to use the DB in a session-level fixture, and will solve my problem. Is there any interest in making that accessible in a more user friendly way? Is this workaround unsupported and prone to break in the future?

@pelme
Copy link
Member

pelme commented Jun 26, 2016

This is something which is worked on and that will be supported by a public API. I tagged this issue with "db-configuration" which is issues related to having more options when it comes to configuring the database. I will update this issue with more information once those changes gets into master!

pelme added a commit to pelme/pytest-django that referenced this issue Jul 3, 2016
@HeyHugo
Copy link

HeyHugo commented Jan 27, 2019

Here's a fixture to enable session level fixtures for db that I use. It's similar to the documented way but also does rollback at the end of the test session.

from django.db import transaction

@pytest.fixture(scope="session")
def initial_test_data(django_db_setup, django_db_blocker):
    with django_db_blocker.unblock():
        # Wrap in try + atomic block to do non crashing rollback
        try:
            with transaction.atomic():
                yield
                raise Exception
        except Exception:
            pass

@pytest.fixture(scope="session", autouse=True)
def some_initial_data(initial_test_data):
    # Data added here will stay in db for the whole test session

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants