我正在尝试设置一些环境变量,以便在一些测试中驱动Django项目的配置,以便我可以模拟一些值,使断言更容易和明确。
我想设置一个环境变量的文件名,该文件名存储一些配置,如果设置了变量并且文件存在,则加载该配置。即:
# proj.settings.py
CONFIG = None
if _filename := os.environ.get('FILE_PATH', None):
with open(_filename) as f:
CONFIG = json.load(f)
我尝试了一个设置环境变量的fixture(参见set_env
),所以我的测试看起来像这样:
# some_app.tests.test_settings.py
import os
@fixture
def data_raw():
return dict(
foo="bar"
)
@fixture
def data_file(data_raw):
with NamedTemporaryFile(mode="w+") as f:
json.dump(data_raw, f)
yield f.name
@fixture
def set_env(data_file):
os.environ['FILE_PATH'] = data_file
def test_it_loads_data(set_env, data_raw, settings):
assert settings.CONFIG == data_raw
但是set_env
不会在Django配置之前执行,所以CONFIG
不会被设置。
Django设置在导入时运行,因此它将在任何fixture之前执行。
您也可以通过在导入时设置环境变量来解决这个问题:
os.environ['FILE_PATH'] = ...
def test_it_loads_data(set_env, data_raw, settings):
assert settings.CONFIG == data_raw
但话虽如此,我不认为这是最好的测试方法。我认为最好将逻辑移动到一个单独的函数中,然后自己测试它:
# utils.py
def loan_config():
if _filename := os.environ.get('FILE_PATH', None):
with open(_filename) as f:
return json.load(f)
return None
# settings.py
CONFIG = loan_config()
然后单独测试load_config
:
from tempfile import NamedTemporaryFile
import json
def test_load_config():
mock_data = {"key": "value"}
# Create a temp file with the mock data
with NamedTemporaryFile("w", suffix=".json", delete=False) as temp_file:
json.dump(mock_data, temp_file)
temp_file.close()
# Store the temp file path in an env variable
os.environ["FILE_PATH"] = temp_file.name
# Call the loan_config function
result = loan_config()
# Assert that the function returns the file parsed by json
assert result == mock_data
# Clean up the temp file
os.remove(temp_file.name)
您可能还应该在测试完成后恢复FILE_PATH环境的先前值。否则,这将是一个"漏"字。测试