mardi 30 juin 2015

Django: Override Setting used in AppConfig Ready Function

We are trying to write an automated test for the behavior of the AppConfig.ready function, which we are using as an initialization hook to run code when the Django app has loaded. Our ready method implementation uses a Django setting that we need to override in our test, and naturally we're trying to use the override_settings decorator to achieve this.

There is a snag however - when the test runs, at the point the ready function is executed, the setting override hasn't kicked in (it is still using the original value from settings.py). Is there a way that we can still override the setting in a way where the override will apply when the ready function is called?

Some code to demonstrate this behavior:

settings.py

MY_SETTING = 'original value'

dummy_app/__init__.py

default_app_config = 'dummy_app.apps.DummyAppConfig'

dummy_app/apps.py

from django.apps import AppConfig
from django.conf import settings


class DummyAppConfig(AppConfig):
    name = 'dummy_app'

    def ready(self):
        print('settings.MY_SETTING in app config ready function: {0}'.format(settings.MY_SETTING))

dummy_app/tests.py

from django.conf import settings
from django.test import TestCase
from django.test.utils import override_settings


@override_settings(MY_SETTING='overridden value')
@override_settings(INSTALLED_APPS=('dummy_app',))
class AppConfigTests(TestCase):

    def test_to_see_where_overridden_settings_value_is_available(self):
        print('settings.MY_SETTING in test function: '.format(settings.MY_SETTING))
        self.fail('Trigger test output')

Output

======================================================================
FAIL: test_to_see_where_overridden_settings_value_is_available (dummy_app.tests.AppConfigTests)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/labminds/venv/labos/src/dom-base/dummy_app/tests.py", line 12, in test_to_see_where_overridden_settings_value_is_available
    self.fail('Trigger test output')
AssertionError: Trigger test output
-------------------- >> begin captured stdout << ---------------------
settings.MY_SETTING in app config ready function: original value
settings.MY_SETTING in test function: overridden value

--------------------- >> end captured stdout << ----------------------

It is important to note that we only want to override this setting for the tests that are asserting the behavior of ready, which is why we aren't considering changing the setting in settings.py, or using a separate version of this file used just for running our automated tests.

One option already considered - we could simply initialize the AppConfig class in our test, call ready and test the behavior that way (at which point the setting would be overridden by the decorator). However, we would prefer to run this as an integration test, and rely on the natural behavior of Django to call the function for us - this is key functionality for us and we want to make sure the test fails if Django's initialization behavior changes.

Aucun commentaire:

Enregistrer un commentaire