2015-07-02 20 views
10

Desidero essere in grado di impostare le variabili di ambiente nella mia app Django affinché i test possano essere eseguiti. Ad esempio, le mie opinioni si basano su diverse chiavi API.django impostazione delle variabili di ambiente nei test di unestest

Ci sono modi per override settings during testing, ma non li voglio definiti in settings.py poiché si tratta di un problema di sicurezza.

Ho provato nella mia funzione di impostazione per impostare queste variabili di ambiente, ma ciò non funziona per dare all'applicazione Django i valori.

class MyTests(TestCase): 
    def setUp(self): 
     os.environ['TEST'] = '123' # doesn't propogate to app 

quando prova a livello locale, ho semplicemente hanno un .env file di corro con

foreman start -e .env web 

che fornisce os.environ con i valori. Ma in Django unittest.TestCase non ha un modo (che io sappia) per impostarlo.

Come posso aggirare questo?

+2

Hai provato a usare [EnvironmentVarGuard] (https://docs.python.org/2/library/test.html#test.test_support.EnvironmentVarGuard)? – schillingt

+0

Sì, quella era la risposta giusta! – lollercoaster

risposta

7

Come ha notato @schillingt nei commenti, EnvironmentVarGuard era il modo corretto.

from test.test_support import EnvironmentVarGuard 
from django.test import TestCase 

class MyTestCase(TestCase): 
    def setUp(self): 
     self.env = EnvironmentVarGuard() 
     self.env.set('VAR', 'value') 

    def test_something(self): 
     with self.env: 
      # ... perform tests here ... # 
      pass 

Questa imposta correttamente le variabili d'ambiente per tutta la durata della dichiarazione oggetto contesto with.

+1

Genera un errore di importazione. Inoltre, la documentazione per EnvironmentVarGuard afferma: "Attenzione Il pacchetto di test è pensato per l'uso interno solo da Python ed è documentato a beneficio degli sviluppatori core di Python.Un utilizzo di questo pacchetto al di fuori della libreria standard di Python è sconsigliato come menzionato nel codice qui può cambiare o essere rimosso senza preavviso tra le versioni di Python. " – Nate

+3

python 3 lo ha spostato su 'da test.support import EnvironmentVarGuard'. Tuttavia, se preferisci non dipendere dal codice di uso interno, puoi copiare l'implementazione [python 2.7 di EnvironmentVarGuard] (https://github.com/python/cpython/blob/2.7/Lib/test/test_support .py # L957-L1001) nel proprio codice: è piuttosto semplice. – medmunds

0

Io uso py.test come runner di test e consente di creare un file pytest.ini in cui è possibile specificare un particolare file di impostazioni da utilizzare durante l'esecuzione dei test.

Vedere documentazione su questo qui:

http://pytest-django.readthedocs.org/en/latest/configuring_django.html#pytest-ini-settings

vi consiglio py.test in generale come un corridore di prova, perché supporta diversi tipi di classi di test e funzioni anche semplici, ed è abbastanza facile da impostare up fixture o altro codice che viene eseguito prima e dopo i test.

+0

Ecco come modificare i file 'settings.py', non le variabili d'ambiente. Le mie chiamate API, ad esempio AWS, ecc. Sono fatte con costruttori che cercano variabili d'ambiente, non impostazioni di Django. – lollercoaster

+0

Hai detto "Esistono modi per ignorare le impostazioni durante i test, ma non li voglio definiti in settings.py dato che si tratta di un problema di sicurezza." Non riesco a vedere come la definizione delle variabili in un file di impostazioni che viene utilizzato * solo * dal runner di test è un problema di sicurezza. – erewok

+0

Avrei dovuto essere più chiaro. Ci sono due problemi. 1) sicurezza, non commit credenziali, 2) il mio flusso di lavoro con le variabili d'ambiente usso 'boto' e altre API per cui vorrei essere in grado di usarle. Stavo solo disegnando l'analogia con settings.py – lollercoaster

0

Vecchia domanda, ma è comparso in una ricerca su Google e nessuna delle risposte esistenti è adatta. Se stai usando pytest, env vars può essere impostato/ripristinato usando pytest's monkeypatching functionality.

13

Il test.support.EnvironmentVarGuard è un'API interna che può essere modificata da versione a versione con modifiche interrotte (incompatibili all'indietro). Infatti, l'intero pacchetto test è solo per uso interno. Nella pagina di documentazione del pacchetto di test è stato indicato esplicitamente che è per il test interno delle librerie principali e NON un'API pubblica. (Vedi link sotto)

Si dovrebbe usare patch.dict() in lib serie di pitone unittest.mock. Può essere utilizzato come gestore del contesto, decoratore o decoratore di classe. Vedi il codice di esempio qui sotto copiato dalla documentazione ufficiale di Python.

import os 
from unittest.mock import patch 
with patch.dict('os.environ', {'newkey': 'newvalue'}): 
    print(os.environ['newkey']) # should print out 'newvalue' 
    assert 'newkey' in os.environ # should be True 
assert 'newkey' not in os.environ # should be True 

Update: per chi non legge la documentazione a fondo e potrebbe avere perso la nota, per saperne di più test note pacchetto a

https://docs.python.org/2/library/test.html o

https://docs.python.org/3/library/test.html

+2

@seb nel link che hai fornito, è ancorato a 'class test.test_support.EnvironmentVarGuard', in altre parole, fa parte del pacchetto' test', che è un pacchetto di test di regressione per ** Python **. E poi scorrere la pagina ALL THE WAY UP, leggere la nota nella seconda riga subito dopo il titolo: _Note Il pacchetto di test è pensato per l'uso interno solo da Python. È documentato a beneficio degli sviluppatori core di Python. Qualsiasi utilizzo di questo pacchetto al di fuori della libreria standard di Python è sconsigliato in quanto il codice menzionato qui può essere modificato o rimosso senza preavviso tra le versioni di Python._ – Devy

1

Se sei caricamento delle variabili di ambiente nel file settings.py di Django in questo modo:
import os ENV_NAME = os.environ.get('ENV_NAME', 'default')
È possibile utilizzare questo:
from django.test import TestCase, override_settings @override_settings(ENV_NAME="super_setting") def test_...(self):

Problemi correlati