2015-06-30 28 views
6

Staramy się napisać test automatyczny dla zachowania funkcji AppConfig.ready, której używamy jako haczyka inicjalizacyjnego do uruchomienia kodu po załadowaniu aplikacji Django. Nasza implementacja metody wykorzystuje ustawienie Django, które musimy przesłonić w naszym teście i naturalnie próbujemy użyć dekoratora override_settings, aby to osiągnąć.Django: Zastąpienie Ustawienie używane w funkcji Ready AppConfig

Istnieje jednak problem - podczas wykonywania testu w momencie wykonania funkcji ready, zmiana ustawień nie została uruchomiona (nadal wykorzystuje oryginalną wartość z settings.py). Czy istnieje sposób, że możemy nadal przesłonić ustawienie w sposób, w którym będzie obowiązywać nadpisanie, gdy zostanie wywołana funkcja ready?

Niektóre kodu do wykazania tego zachowania:

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

Wyjście

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

Ważne jest, aby pamiętać, że tylko chce zmienić to ustawienie dla testów, które są dochodzeniu do zachowanie ready, dlatego nie zastanawiamy się nad zmianą ustawienia w settings.py lub przy użyciu oddzielnego Ten plik służy wyłącznie do prowadzenia naszych automatycznych testów.

Jedna z opcji już rozważona - możemy po prostu zainicjować klasę AppConfig w naszym teście, zadzwonić pod numer ready i przetestować zachowanie w ten sposób (w którym punkcie ustawienie zostanie przesłonięte przez dekorator). Wolelibyśmy jednak uruchomić to jako test integracyjny i polegać na naturalnym zachowaniu Django, aby wywołać funkcję dla nas - jest to dla nas kluczowa funkcjonalność i chcemy upewnić się, że test się nie powiedzie, jeśli zmieni się zachowanie inicjacyjne Django.

Odpowiedz

1

Niektóre pomysły (inny wysiłek i zautomatyzowane wiarygodności):

  • Nie testuj integracyjnej, i opierają się na czytanie RELEAS notatki/popełnia przed uaktualnieniem wersji Django i/lub polegać na pojedynczym ręcznego testowania
  • Zakładając test - wdrożenie etapowe - wdrożenie potrójnego wdrożenia, należy przetestować poszczególne przypadki w izolacji i dodać test integracji jako test dymu wdrażania (np. Ujawniając tę ​​wartość ustawienia za pomocą polecenia zarządzania lub wewnętrznego punktu końcowego URL) - tylko sprawdź, czy w przypadku inscenizacji ma wartość, jaką powinno być dla przemieszczania. Nieco opóźnione sprzężenie zwrotne w porównaniu z testami jednostkowymi
  • przetestuj to przez ramy testowe poza własnym Django - tj.: Napisać unittest s (lub py.test S) i wewnątrz tych testów bootstrap django w każdym teście (choć trzeba sposobem importowania & manipulować ustawienia)
  • użyć kombinacji nadrzędne ustawienia przez środowisko systemu operacyjnego użytkownika (użyliśmy envdir a'la 12 factor app) oraz polecenie zarządzania, który zrobi test (y) - np: MY_SETTING='overridden value' INSTALLED_APPS='dummy_app' EXPECTED_OUTCOME='whatever' python manage.py ensure_app_config_initialized_as_expected
  • patrząc na Django's own app init testsapps.clear_cache() i with override_settings(INSTALLED_APPS=['test_app']): config = apps.get_app_config('test_app') assert config.... mógł pracować, choć nigdy nie próbowałem