python - dotenv - Django configurando variables de entorno en pruebas de prueba de unidad
environ python (7)
Quiero poder establecer variables de entorno en mi aplicación Django para que las pruebas puedan ejecutarse. Por ejemplo, mis puntos de vista se basan en varias claves API.
Hay formas de anular la configuración durante las pruebas , pero no quiero que se definan en settings.py
ya que es un problema de seguridad.
He intentado en mi función de configuración configurar estas variables de entorno, pero eso no funciona para dar los valores a la aplicación Django.
class MyTests(TestCase):
def setUp(self):
os.environ[''TEST''] = ''123'' # doesn''t propogate to app
Cuando .env
localmente, simplemente tengo un archivo .env
el que corro
foreman start -e .env web
que suministra os.environ
con valores. Pero en el unittest.TestCase
de Django no hay una manera (que yo sepa) de establecer eso.
¿Cómo puedo evitar esto?
Como @schillingt señaló en los comentarios, EnvironmentVarGuard era la forma correcta.
from test.test_support import EnvironmentVarGuard # Python(2.7 < 3)
from test.support import EnvironmentVarGuard # Python >=3
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
Esto establece correctamente las variables de entorno para la duración del objeto de contexto with
declaración.
Inicialmente, mi variable env PARTNER_CODE
estaba configurada en wow
.
Pude cambiar la variable env usando lo siguiente:
from test.support import EnvironmentVarGuard
with EnvironmentVarGuard() as env:
env[''PARTNER_CODE''] = ''sos''
Ahora mi variable env PARTNER_CODE
dice sos
.
Pregunta anterior, pero apareció en una búsqueda de Google y ninguna de las respuestas existentes es adecuada. Si está usando pytest, las variables env se pueden configurar / restaurar utilizando la funcionalidad de pypest monkeypatching .
Si está cargando sus variables de entorno en el archivo settings.py
de Django como este:
import os
ENV_NAME = os.environ.get(''ENV_NAME'', ''default'')
Podrías usar esto:
from django.test import TestCase, override_settings
@override_settings(ENV_NAME="super_setting")
def test_...(self):
Usar EnvironmentVarGuard
no es una buena solución ya que falla en algunos entornos y funciona en otros. ver ejemplo a continuación.
Una solución mejor es lo que sugirió erewok que requiere el uso de unittest.mock
en python3.
Suponiendo que usa unittest
from unittest.mock import patch
class TestCase(unittest.TestCase):
def setUp(self):
self.env = patch.dict(''os.environ'', {''hello'':''world''})
def test_scenario_1(self):
with self.env:
self.assertEqual(os.environ.get(''hello''), ''world'')
`` `
Utilizo py.test
como mi corredor de prueba, y le permite crear un archivo pytest.ini
en el que puede especificar un archivo de configuración particular para usar al ejecutar pruebas.
Vea la documentación sobre esto aquí:
http://pytest-django.readthedocs.org/en/latest/configuring_django.html#pytest-ini-settings
Recomiendo py.test en general como un corredor de prueba, porque admite diferentes tipos de clases de prueba e incluso funciones simples, y es bastante fácil configurar dispositivos u otro código que se ejecute antes y después de las pruebas.
test.support.EnvironmentVarGuard
es una API interna que puede cambiarse de una versión a otra con cambios de ruptura (incompatibles con versiones anteriores). De hecho, todo el paquete de test
es solo para uso interno. Se indicó explícitamente en la página de documentación del paquete de prueba que es para pruebas internas de bibliotecas principales y NO una API pública. (ver enlaces abajo)
Deberías usar patch.dict()
en la patch.dict()
estándar de python unittest.mock
. Se puede utilizar como administrador de contexto, decorador o decorador de clase. Vea el código de ejemplo a continuación copiado de la documentación oficial de 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
Actualización: para aquellos que no leen la documentación a fondo y pueden haberse perdido la nota, lea más notas del paquete de test
en