Je veux pouvoir définir des variables d'environnement dans mon application Django pour que des tests puissent être exécutés. Par exemple, mes vues reposent sur plusieurs clés d’API.
Il existe des moyens pour remplacer les paramètres pendant le test , mais je ne veux pas qu'ils soient définis dans settings.py
car c'est un problème de sécurité.
J'ai essayé dans ma fonction de configuration de définir ces variables d'environnement, mais cela ne fonctionne pas pour donner les valeurs à l'application Django.
class MyTests(TestCase):
def setUp(self):
os.environ['TEST'] = '123' # doesn't propogate to app
Lorsque je teste localement, j’ai simplement un fichier .env
avec lequel je lance
foreman start -e .env web
qui fournit os.environ
avec des valeurs. Mais dans le unittest.TestCase
de Django, il n’a pas de moyen (que je sache) de le définir.
Comment puis-je contourner cela?
Comme @schillingt l'a noté dans les commentaires, EnvironmentVarGuard était le bon moyen.
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
Cela définit correctement les variables d'environnement pour la durée de l'instruction with
de l'objet de contexte.
test.support.EnvironmentVarGuard
est une API interne qui peut être modifiée de version en version avec des modifications de rupture (incompatibles en amont). En fait, l'intégralité du package test
est à usage interne uniquement. Il a été explicitement indiqué sur la page de documentation du package de test qu'il s'agissait d'un test interne des bibliothèques principales et NON d'une API publique. (voir les liens ci-dessous)
Vous devez utiliser patch.dict()
dans la bibliothèque standard de python unittest.mock
. Il peut être utilisé en tant que gestionnaire de contexte, décorateur ou décorateur de classe. Voir l'exemple de code ci-dessous, copié de la documentation officielle 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
Mise à jour: pour ceux qui ne lisent pas la documentation à fond et qui ont peut-être manqué la note, lisez plus de notes sur le paquet test
à
L'utilisation de EnvironmentVarGuard
n'est pas une bonne solution car elle échoue dans certains environnements et fonctionne dans d'autres. voir exemple ci-dessous.
Une meilleure solution est celle suggérée par erewok qui nécessite l’utilisation du unittest.mock
en python3.
En supposant d'utiliser 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')
`` `
Si vous chargez vos variables d'environnement dans le fichier settings.py
de Django, procédez comme suit:
import os
ENV_NAME = os.environ.get('ENV_NAME', 'default')
Vous pouvez utiliser ceci:
from Django.test import TestCase, override_settings
@override_settings(ENV_NAME="super_setting")
def test_...(self):
J'utilise py.test
comme testeur, et cela vous permet de créer un fichier pytest.ini
dans lequel vous pouvez spécifier un fichier de paramètres particulier à utiliser lors de l'exécution de tests.
Voir la documentation à ce sujet ici:
http://pytest-Django.readthedocs.org/en/latest/configuring_Django.html#pytest-ini-settings
Je recommande généralement py.test en tant que lanceur de tests, car il prend en charge différents types de classes de test et même des fonctions simples, et il est assez facile de configurer des fixtures ou tout autre code s'exécutant avant et après les tests.
Ancienne question, mais elle est apparue dans une recherche Google et aucune des réponses existantes ne convient. Si vous utilisez pytest, env vars peut être défini/restauré à l’aide de la fonctionnalité monkeypatching de pytest .
Initialement, ma variable env PARTNER_CODE
a été définie sur wow
.
J'ai pu changer la variable env en utilisant les éléments suivants:
from test.support import EnvironmentVarGuard
with EnvironmentVarGuard() as env:
env['PARTNER_CODE'] = 'sos'
Maintenant, ma variable env PARTNER_CODE
dit sos
.