Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pytest and Django settings runtime changes

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
like image 302
Quba Avatar asked Nov 08 '16 20:11

Quba


1 Answers

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 ...
like image 176
Frank T Avatar answered Oct 04 '22 22:10

Frank T