我正在为Flask应用程序的配置文件编写测试。为了确保系统中设置的env变量不影响测试结果,我使用pytest的monkeypatch来创建可预测的测试结果。
我在' clean'中测试配置文件一次。一个没有设置env变量的灯具的状态和一个假的'配置,我想让monkeypatch在运行测试之前设置变量。
两个灯具都设置了env变量,然后在将配置对象传递给测试函数之前导入它。
当配置对象加载到文档的头部而不是夹具内部时,两个夹具都使用基于实际系统env变量的版本。
似乎第二个灯具不会导入配置对象,而是重用cleanConfig灯具创建的灯具。如何强制夹具重新导入配置对象?
test_config.py:
import pytest
from config import config
class TestConfigSettings(object):
@pytest.fixture(scope='function')
def cleanConfig(config_name, monkeypatch):
def makeCleanConfig(config_name):
monkeypatch.delenv('SECRET_KEY', raising=False)
monkeypatch.delenv('DEV_DATABASE_URL', raising=False)
from config import config
configObject = config[config_name]
return configObject
return makeCleanConfig
@pytest.fixture(scope='function')
def fakeEnvConfig(config_name, monkeypatch):
def makeFakeEnvConfig(config_name):
monkeypatch.setenv('SECRET_KEY', 'fake difficult string')
monkeypatch.setenv('DEV_DATABASE_URL', 'postgresql://fake:5432/fakeDevUrl')
from config import config
configObject = config[config_name]
return configObject
return makeFakeEnvConfig
def test_configObject_withDevelopmentConfig_containsCorrectSettings(self, cleanConfig):
configObject = cleanConfig('development')
assert configObject.SECRET_KEY == 'hard to guess string'
assert configObject.DEBUG == True
assert configObject.SQLALCHEMY_DATABASE_URI == None
def test_configObject_withDevelopmentConfigAndEnvSet_copiesEnvSettings(self, fakeEnvConfig):
configObject = fakeEnvConfig('development')
assert configObject.SECRET_KEY == 'fake difficult string'
assert configObject.SQLALCHEMY_DATABASE_URI == 'postgresql://fake:5432/fakeDevUrl'
Config.py:
class Config:
SECRET_KEY = os.environ.get('SECRET_KEY') or 'hard to guess string'
class DevelopmentConfig(Config):
DEBUG = True
SQLALCHEMY_DATABASE_URI = os.environ.get('DEV_DATABASE_URL')
config = {
'default': DevelopmentConfig,
'development': DevelopmentConfig,
...
}
答案 0 :(得分:0)
我终于找到了解决问题的方法。通过使用reload()函数,您可以在更改内容(在这种情况下加载的env变量)后再次导入模块。为了能够使用它,我必须将导入更改为配置模块,而不是之前导入的配置字典,因为reload()对象仅适用于模块。 新代码:
import pytest
from importlib import reload
import config
class TestConfigSettings(object):
@pytest.fixture(scope='function')
def cleanConfig(config_name, monkeypatch):
def makeCleanConfig(config_name):
monkeypatch.delenv('SECRET_KEY', raising=False)
monkeypatch.delenv('DEV_DATABASE_URL', raising=False)
reload(config)
configObject = config.config[config_name]
return configObject
return makeCleanConfig
@pytest.fixture(scope='function')
def fakeEnvConfig(config_name, monkeypatch):
def makeFakeEnvConfig(config_name):
monkeypatch.setenv('SECRET_KEY', 'fake difficult string')
monkeypatch.setenv('DEV_DATABASE_URL', 'postgresql://fake:5432/fakeDevUrl')
reload(config)
configObject = config.config[config_name]
return configObject
return makeFakeEnvConfig