简体   繁体   English

如何在pytest中设置环境变量

[英]How to set environment variable in pytest

I have a lamba handler that uses an environment variable.我有一个使用环境变量的 Lamba 处理程序。 How can I set that value using pytest.如何使用 pytest 设置该值。 I'm getting the error我收到错误

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

I tried setting in the test like this我尝试在测试中像这样设置

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):
...

You're getting the failure before your monkeypatch is able to run.在您的monkeypatch 能够运行之前,您就遇到了故障。 The loading of the environment variable will happen when the runner module is first imported.环境变量的加载将在首次导入 runner 模块时发生。

If this is a module you own, I'd recommend modifying the code to use a default value if DATA_ENGINEERING_BUCKET isn't set.如果这是您拥有的模块,如果未设置 DATA_ENGINEERING_BUCKET,我建议修改代码以使用默认值。 Then you can modify it's value to whatever you want at runtime by calling module.DATA_ENGINEERING_BUCKET = "my_bucket" .然后您可以在运行时通过调用module.DATA_ENGINEERING_BUCKET = "my_bucket"将其值修改为您想要的任何值。

DATA_ENGINEERING_BUCKET = os.environ.get("BUCKET", default="default_bucket")

If you can't modify that file then things are more complicated.如果您无法修改该文件,那么事情就会变得更加复杂。

I looked into creating a global fixture that monkeypatches the environment and loads the module once, before any tests load and received a pytest error about using function level fixtures within a session level fixture.我研究了创建一个全局装置,在任何测试加载之前,对环境进行猴子补丁并加载一次模块,并收到有关在会话级装置中使用函数级装置的 pytest 错误。 Which makes sense monkeypatch really isn't intended to fake things long term.这很有意义,monkeypatch 真的不是为了长期伪造东西。 You can stick the module load into your test after the monkeypatch but that will generate a lot of boilerplate.您可以在monkeypatch 之后将模块负载粘贴到您的测试中,但这会生成大量样板文件。

What eventually worked creating a fixture that will provide the class in lieu of importing it.最终创建了一个夹具来提供类而不是导入它。 The fixture;夹具; sets os.environ to the desired value, loads the module, resets os.environ to it's origional value then yields the module.os.environ设置为所需的值,加载模块,将 os.environ 重置为其原始值,然后生成模块。 Any tests that need this module can request the fixture to have access to it within their scope.任何需要此模块的测试都可以请求夹具在其范围内访问它。 A word of caution, because test files are imported before fixtures are run any test files that don't use the fixture and import the module normally will raise a KeyError and cause pytest to crash before running any tests.需要注意的是,因为测试文件是在运行夹具之前导入的,任何不使用夹具并正常导入模块的测试文件都会引发 KeyError 并导致 pytest 在运行任何测试之前崩溃。

conftest.py 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测试.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

A potentially simpler method一种可能更简单的方法

os.environ is a dictionary of environment variables that is created when os first loads. os.environ是在 os 首次加载时创建的环境变量字典。 If you want a single value for every test then you just need to add the value you want to it before loading any test modules.如果您希望每个测试都有一个值,那么您只需要在加载任何测试模块之前添加您想要的值。 If you put os.environ['BUCKET'] = 'test-bucket' at the top of conftest.py you will set the environment variable for the rest of the test session.如果您将os.environ['BUCKET'] = 'test-bucket'放在 conftest.py 的顶部,您将为测试会话的其余部分设置环境变量。 Then as long as the first import of the module happens afterwards you won't have a key error.然后只要模块的第一次导入发生在之后,您就不会出现关键错误。 The big downside to this approach is that unless you know to look in conftest.py or grep the code it will be difficult to determine where the environment variable is getting set when troubleshooting.这种方法的最大缺点是,除非您知道查看 conftest.py 或 grep 代码,否则在进行故障排除时很难确定环境变量的设置位置。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM