如何在pytest中设置环境变量
How to set environment variable in pytest
我有一个使用环境变量的 lamba 处理程序。如何使用 pytest 设置该值。我收到错误
tests/test_kinesis.py:3: in <module>
from runner import kinesis
runner/kinesis.py:6: in <module>
DATA_ENGINEERING_BUCKET = os.environ["BUCKET"]
../../../../../.pyenv/versions/3.8.8/lib/python3.8/os.py:675: in __getitem__
raise KeyError(key) from None
E KeyError: 'BUCKET'
7:03
我在测试中试过这样设置
class TestHandler(unittest.TestCase):
@mock_s3
@mock_lambda
def test_handler(monkeypatch):
monkeypatch.setenv("BUCKET", "test-bucket")
actual = kinesis.handler(kinesis_stream_event, "")
expected = {"statusCode": 200, "body": "OK"}
assert actual == expected
DATA_ENGINEERING_BUCKET = os.environ["BUCKET"]
def handler(event, context):
...
在您的 monkeypatch 能够 运行 之前,您遇到了失败。首次导入 运行ner 模块时会加载环境变量。
如果这是您拥有的模块,如果未设置 DATA_ENGINEERING_BUCKET,我建议您修改代码以使用默认值。然后您可以在 运行 时间通过调用 module.DATA_ENGINEERING_BUCKET = "my_bucket"
.
将其值修改为任何您想要的值
DATA_ENGINEERING_BUCKET = os.environ.get("BUCKET", default="default_bucket")
如果您不能修改那个文件,那么事情就更复杂了。
我研究了创建一个全局夹具,该夹具会在加载任何测试之前对环境进行猴子修补并加载一次模块,并收到有关在会话级夹具中使用功能级夹具的 pytest 错误。这是有道理的 monkeypatch 真的不是为了长期伪造东西。您可以在 monkeypatch 之后将模块加载到您的测试中,但这会生成大量样板文件。
最终创建一个提供 class 代替导入的固定装置的方法。固定装置;将 os.environ
设置为所需的值,加载模块,将 os.environ 重置为其原始值,然后生成模块。任何需要此模块的测试都可以请求夹具在其范围内访问它。请注意,因为测试文件是在固定装置 运行 之前导入的,任何不使用固定装置并正常导入模块的测试文件都会引发 KeyError 并导致 pytest 在 运行 任何之前崩溃测试。
conftest.py
import os, pytest
@pytest.fixture(scope='session')
def kinesis():
old_environ = os.environ
os.environ = {'BUCKET': 'test-bucket'}
import kinesis
os.environ = old_environ
yield kinesis
tests.py
# Do NOT import kinesis in any test file. Rely on the fixture.
class TestHandler(unittest.TestCase):
@mock_s3
@mock_lambda
def test_handler(kinesis):
actual = kinesis.handler(kinesis_stream_event, "")
expected = {"statusCode": 200, "body": "OK"}
assert actual == expected
一种可能更简单的方法
os.environ
是在 os 首次加载时创建的环境变量字典。如果您希望每个测试都有一个值,那么您只需要在加载任何测试模块之前添加您想要的值。如果将 os.environ['BUCKET'] = 'test-bucket'
放在 conftest.py 的顶部,您将为测试会话的其余部分设置环境变量。然后,只要模块的第一次导入发生在之后,您就不会有关键错误。这种方法的一大缺点是,除非您知道查看 conftest.py 或 grep 代码,否则在进行故障排除时将很难确定环境变量的设置位置。
我有一个使用环境变量的 lamba 处理程序。如何使用 pytest 设置该值。我收到错误
tests/test_kinesis.py:3: in <module>
from runner import kinesis
runner/kinesis.py:6: in <module>
DATA_ENGINEERING_BUCKET = os.environ["BUCKET"]
../../../../../.pyenv/versions/3.8.8/lib/python3.8/os.py:675: in __getitem__
raise KeyError(key) from None
E KeyError: 'BUCKET'
7:03
我在测试中试过这样设置
class TestHandler(unittest.TestCase):
@mock_s3
@mock_lambda
def test_handler(monkeypatch):
monkeypatch.setenv("BUCKET", "test-bucket")
actual = kinesis.handler(kinesis_stream_event, "")
expected = {"statusCode": 200, "body": "OK"}
assert actual == expected
DATA_ENGINEERING_BUCKET = os.environ["BUCKET"]
def handler(event, context):
...
在您的 monkeypatch 能够 运行 之前,您遇到了失败。首次导入 运行ner 模块时会加载环境变量。
如果这是您拥有的模块,如果未设置 DATA_ENGINEERING_BUCKET,我建议您修改代码以使用默认值。然后您可以在 运行 时间通过调用 module.DATA_ENGINEERING_BUCKET = "my_bucket"
.
DATA_ENGINEERING_BUCKET = os.environ.get("BUCKET", default="default_bucket")
如果您不能修改那个文件,那么事情就更复杂了。
我研究了创建一个全局夹具,该夹具会在加载任何测试之前对环境进行猴子修补并加载一次模块,并收到有关在会话级夹具中使用功能级夹具的 pytest 错误。这是有道理的 monkeypatch 真的不是为了长期伪造东西。您可以在 monkeypatch 之后将模块加载到您的测试中,但这会生成大量样板文件。
最终创建一个提供 class 代替导入的固定装置的方法。固定装置;将 os.environ
设置为所需的值,加载模块,将 os.environ 重置为其原始值,然后生成模块。任何需要此模块的测试都可以请求夹具在其范围内访问它。请注意,因为测试文件是在固定装置 运行 之前导入的,任何不使用固定装置并正常导入模块的测试文件都会引发 KeyError 并导致 pytest 在 运行 任何之前崩溃测试。
conftest.py
import os, pytest
@pytest.fixture(scope='session')
def kinesis():
old_environ = os.environ
os.environ = {'BUCKET': 'test-bucket'}
import kinesis
os.environ = old_environ
yield kinesis
tests.py
# Do NOT import kinesis in any test file. Rely on the fixture.
class TestHandler(unittest.TestCase):
@mock_s3
@mock_lambda
def test_handler(kinesis):
actual = kinesis.handler(kinesis_stream_event, "")
expected = {"statusCode": 200, "body": "OK"}
assert actual == expected
一种可能更简单的方法
os.environ
是在 os 首次加载时创建的环境变量字典。如果您希望每个测试都有一个值,那么您只需要在加载任何测试模块之前添加您想要的值。如果将 os.environ['BUCKET'] = 'test-bucket'
放在 conftest.py 的顶部,您将为测试会话的其余部分设置环境变量。然后,只要模块的第一次导入发生在之后,您就不会有关键错误。这种方法的一大缺点是,除非您知道查看 conftest.py 或 grep 代码,否则在进行故障排除时将很难确定环境变量的设置位置。