2015-06-30 12 views
6

Si sta tentando di scrivere un test automatico per il comportamento della funzione AppConfig.ready, che viene utilizzata come hook di inizializzazione per eseguire il codice quando l'app Django è stata caricata. L'implementazione del metodo ready utilizza un'impostazione Django che è necessario ignorare nel nostro test e, naturalmente, stiamo cercando di utilizzare il decoratore override_settings per ottenere questo risultato.Django: Override Impostazione utilizzata in AppConfig Ready Funzione

C'è un intoppo però - quando il test viene eseguito, in corrispondenza del punto viene eseguita la funzione ready, l'override impostazione non ha preso a calci in (si sta ancora utilizzando il valore originale da settings.py). C'è un modo in cui possiamo ancora ignorare le impostazioni in un modo in cui l'override si applica quando viene chiamata la funzione ready?

del codice per illustrare questo comportamento:

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

uscita

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

E 'importante notare che vogliamo solo ignorare questa impostazione per i test che stiamo affermando la comportamento di ready, motivo per cui non stiamo valutando la possibilità di modificare l'impostazione in settings.py o di utilizzare un di questo file utilizzato solo per eseguire i nostri test automatici.

Una possibilità già considerato - potremmo semplicemente inizializzare la classe AppConfig nel nostro test, chiamare ready e testare il comportamento in questo modo (a quel punto l'impostazione sarebbe stata ignorata dal decoratore). Tuttavia, preferiremmo eseguirlo come test di integrazione e fare affidamento sul comportamento naturale di Django per chiamare la funzione per noi: questa è la funzionalità chiave per noi e vogliamo essere sicuri che il test fallisca se il comportamento di inizializzazione di Django cambia.

risposta

1

Alcune idee (sforzo diversa richiesta e automatizzato di controllo):

  • Non test di integrazione, e si basano sulla lettura delle note RELEAS/impegna prima di aggiornare la versione di Django e/o affidamento su singolo test manuale
  • Supponendo una distribuzione fase test - prod deploy pipeline, unit test i casi speciali in isolamento e aggiunge un controllo di integrazione come un test del fumo di distribuzione (es .: esponendo questo valore di impostazione tramite un comando di gestione o un endpoint interno solo url) - solo verificare che per la stadiazione abbia il valore che dovrebbe essere per la stadiazione. Feedback leggermente ritardato rispetto ai test unitari
  • testarlo attraverso un framework di test esterno a quello di Django - vale a dire.: Scrivere i unittest s (o py.test s) e all'interno di questi test bootstrap django in ogni test (anche se avete bisogno di un modo per importare & manipolare le impostazioni)
  • utilizzare una combinazione di modificare le impostazioni dei attraverso l'ambiente del sistema operativo (che abbiamo utilizzato envdir a'la 12 factor app) e un comando di gestione che avrebbe fatto il test (s) - ad esempio: MY_SETTING='overridden value' INSTALLED_APPS='dummy_app' EXPECTED_OUTCOME='whatever' python manage.py ensure_app_config_initialized_as_expected
  • guardando Django's own app init testsapps.clear_cache() e with override_settings(INSTALLED_APPS=['test_app']): config = apps.get_app_config('test_app') assert config.... potrebbe funzionare, se non ho mai provato
Problemi correlati