2015-06-30 4 views
6

Wir versuchen, einen automatisierten Test für das Verhalten der AppConfig.ready-Funktion zu schreiben, die wir als Initialisierungs-Hook zum Ausführen von Code verwenden, wenn die Django-App geladen wurde. Unsere Methodenimplementierung ready verwendet eine Django-Einstellung, die wir in unserem Test überschreiben müssen, und natürlich versuchen wir, den override_settings Dekorator zu verwenden, um dies zu erreichen.Django: Überschreibungseinstellung in AppConfig verwendet Ready-Funktion

Es gibt jedoch einen Haken - wenn der Test ausgeführt wird, an dem Punkt, an dem die ready-Funktion ausgeführt wird, hat die Einstellung Override nicht begonnen (es verwendet immer noch den ursprünglichen Wert von settings.py). Gibt es eine Möglichkeit, dass wir die Einstellung so überschreiben können, dass die Überschreibung wirksam wird, wenn die Funktion ready aufgerufen wird?

Einige Code, um dieses Verhalten zu zeigen:

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') 

Ausgabe

====================================================================== 
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 << ---------------------- 

Es ist wichtig zu beachten, dass wir diese Einstellung für die Tests nur außer Kraft setzen möchten, dass die Geltendmachung werden Verhalten von ready, weshalb wir nicht in Betracht ziehen, die Einstellung in settings.py zu ändern, oder eine separate Vers Diese Datei wird nur zum Ausführen unserer automatisierten Tests verwendet.

Eine Option bereits in Erwägung gezogen - wir könnten einfach die AppConfig Klasse in unserem Test initialisieren, ready anrufen und das Verhalten auf diese Weise testen (zu diesem Zeitpunkt würde die Einstellung vom Dekorateur überschrieben werden). Wir würden es jedoch vorziehen, dies als einen Integrationstest auszuführen und uns auf das natürliche Verhalten von Django zu verlassen, um die Funktion für uns aufzurufen - dies ist die Schlüsselfunktionalität für uns und wir wollen sicherstellen, dass der Test fehlschlägt, wenn sich Djangos Initialisierungsverhalten ändert.

Antwort

1

Einige Ideen (unterschiedliche Aufwand und automatisierte Sicherheit):

  • Nicht Integrationstest, und verlassen sich auf die releas Noten lesen/verpflichtet, bevor die Django Version aktualisieren und/oder sich auf einzelne manuelle Tests
  • Unter der Annahme einer Test - Phase Deploy - Prod Deploy - Pipeline, Unit - Test die Sonderfälle isoliert und fügen Sie eine Integrationsprüfung als Deployment Smoke Test (zB: durch Setzen dieser Einstellungen Wert über einen Verwaltungsbefehl oder nur interne URL - Endpunkt) vergewissern Sie sich, dass für die Bereitstellung der Wert für die Inszenierung festgelegt ist. Etwas verzögerte Rückmeldung im Vergleich zu Komponententests
  • Testen Sie es durch einen Test-Framework außerhalb von Django eigenen - d.: Die unittest s (oder py.test s) und innerhalb dieser Tests bootstrap django in jedem Test schreiben (obwohl Sie brauchen eine Möglichkeit, um die Einstellungen zu importieren & manipulieren) haben
  • verwenden eine Kombination aus übergeordneten Einstellungen über das Betriebssystemes der Umgebung (wir envdir verwendet a'la 12 factor app) und ein Management-Befehl, der den Test durchführen würde (n) - zB: MY_SETTING='overridden value' INSTALLED_APPS='dummy_app' EXPECTED_OUTCOME='whatever' python manage.py ensure_app_config_initialized_as_expected
  • bei der Suche Django's own app init testsapps.clear_cache() und with override_settings(INSTALLED_APPS=['test_app']): config = apps.get_app_config('test_app') assert config.... arbeiten konnte, obwohl ich habe es nie versucht