Pytest and Django settings runtime changes
Asked Answered
I

3

13

I have a receiver that needs to know whether DEBUG set to True in my settings.py.

from django.conf import settings
...
@receiver(post_save, sender=User)
def create_fake_firebaseUID(sender, instance, created=False, **kwargs):
    # Fake firebaseUID if in DEBUG mode for development purposes
    if created and settings.DEBUG:
        try:
            instance.userprofile
        except ObjectDoesNotExist:
            UserProfile.objects.create(user=instance, firebaseUID=str(uuid.uuid4()))

The problem is that when I create a user using manage.py shell everything works as expected. However, if I run my tests via py.test, the value of settings.DEBUG changes to False. If I check it in conftest.py in pytest_configure, DEBUG is set to True. It changes somewhere later and I have no idea where.

What can cause this? I am sure that I do not change it anywhere in my code.

Edit.

conftest.py

import uuid

import pytest
import tempfile
from django.conf import settings
from django.contrib.auth.models import User


@pytest.fixture(scope='session', autouse=True)
def set_media_temp_folder():
    with tempfile.TemporaryDirectory() as temp_dir:
        settings.MEDIA_ROOT = temp_dir
        yield None


def create_normal_user() -> User:
    username = str(uuid.uuid4())[:30]
    user = User.objects.create(username=username)
    user.set_password('12345')
    user.save()
    return user


@pytest.fixture
def normal_user() -> User:
    return create_normal_user()


@pytest.fixture
def normal_user2() -> User:
    return create_normal_user()

myapp/tests/conftest.py

# encoding: utf-8
import os

import pytest
from django.core.files.uploadedfile import SimpleUploadedFile

from userprofile.models import ProfilePicture


@pytest.fixture
def test_image() -> bytes:
    DIR_PATH = os.path.dirname(os.path.realpath(__file__))
    with open(os.path.join(DIR_PATH, 'test_image.jpg'), 'rb') as f:
        yield f


@pytest.fixture
def profile_picture(test_image, normal_user) -> ProfilePicture:
    picture = SimpleUploadedFile(name='test_image.jpg',
                                 content=test_image.read(),
                                 content_type='image/png')
    profile_picture = ProfilePicture.objects.get(userprofile__user=normal_user)
    profile_picture.picture = picture
    profile_picture.save()
    return profile_picture

pytest.ini

[pytest]
addopts = --reuse-db
DJANGO_SETTINGS_MODULE=mysite.settings
Indetermination answered 8/11, 2016 at 20:42 Comment(3)
It's hard to say why your tests are showing DEBUG as False if you don't provide the code for your tests. It would also be helpful to see your conftest.py.Humbuggery
Also, are you using the import from django.conf import settings? If you import your settings module directly, this can cause strange issues.Humbuggery
@MichaelMior I've never had strange issues but that was indeed my issue.Headdress
L
15

Apparently pytest-django explicitly sets DEBUG to False (source code link).

Diving through the git history of pytest-django a bit, this was done to match Django's default behavior (pytest commit link).

From the Django docs:

Regardless of the value of the DEBUG setting in your configuration file, all Django tests run with DEBUG=False. This is to ensure that the observed output of your code matches what will be seen in a production setting.

As a workaround you can use pytest-django's settings fixture to override so DEBUG=True if you need it to be. For example,

def test_my_thing(settings):
    settings.DEBUG = True
    # ... do your test ...
Lorrianelorrie answered 4/3, 2019 at 18:53 Comment(1)
Note that this only works if your import your settings like so from django.conf import settings and not directly.Headdress
I
7

For anyone who is having similar problem. I found the reason. I downloaded source files of pytest-django and found out that it sets DEBUG to False in pytest-django/pytest_django/plugin.py:338. I do not know why tho.

Indetermination answered 10/11, 2016 at 12:53 Comment(1)
Thanks for this answer, I did some digging based on it and I put up another answer with some explanation. But IMO you have it exactly right. Hopefully the added context will help someone else out.Lorrianelorrie
P
4

Add the following line in the pytest.ini file:

django_debug_mode = True
Pettifogging answered 20/1, 2021 at 2:33 Comment(1)
This worked for me while using pytest-djangoThelmathem

© 2022 - 2024 — McMap. All rights reserved.