如何将环境变量传递给pytest

sri*_*249 45 pytest

在我开始在python项目中执行测试之前,我读了一些环境变量并设置了一些读取这些值的变量.我的测试将根据读取的这些值在所需的环境中运行.

例如:假设环境变量被称为"ENV_NAME"和"ENV_NUMBER"

现在,我想使用py.test运行测试

如果我硬编码这些环境变量,例如:ENV_NAME ='staging',我的代码中的ENV_NUMBER ='5'然后通过在项目目录的根目录执行py.test命令来运行测试,所有测试都成功运行.

但是,我不想硬编码这些值.有没有办法,我可以将这些环境变量作为py.test的命令行参数发送?

我的想法更多

py.test -ENV_NAME ='staging'-ENV_NUMBER ='5'.但是,这不起作用.

请帮忙!谢谢!

tut*_*uju 45

另一种方法是使用pytest-env插件.它可以像这样配置:

[pytest]
env = 
    HOME=~/tmp
    D:RUN_ENV=test
Run Code Online (Sandbox Code Playgroud)

D:前缀允许设置的默认值,而不是覆盖传递到现有的变量py.test.

注意:如果您有时只需要运行专门的环境设置,则可以使用自定义配置显式运行pytest:

pytest -c custom_pytest.ini
Run Code Online (Sandbox Code Playgroud)

  • pytest-env 看起来已经不存在了,而 [python-dotenv](https://github.com/theskumar/python-dotenv) 仍然活跃。 (4认同)
  • [看起来像](https://pypi.org/project/pytest-env/#history) pytest-env 已于 2022 年 10 月更新以添加类型提示。 (3认同)
  • 使用 [pytest-dotenv](https://github.com/quiqua/pytest-dotenv) 成功获取了我的 .env 文件中定义的环境变量,并使其在运行“pytest”时可用。 (2认同)
  • @sourcream 您在使用 pytest-env 时是否遇到任何问题,或者只是注意到它已经有一段时间没有更新了(哇五年了)?python-dotenv 有一组略有不同的用例;我很想听听您如何使用 pytest 更新环境变量 (2认同)

Inf*_*ion 24

除了其他答案。有一个选项可以pytest_generate_testsconftest.py那里覆盖和设置 ENV 变量。

例如,将以下内容添加到conftest.py

import os

def pytest_generate_tests(metafunc):
    os.environ['TEST_NAME'] = 'My super test name| Python version {}'.format(python_version)
Run Code Online (Sandbox Code Playgroud)

此代码将允许您TEST_NAME在测试应用程序中获取ENV 变量。你也可以做一个固定装置:

import os
import pytest

@pytest.fixture
def the_name():
    return os.environ.get('TEST_NAME')
Run Code Online (Sandbox Code Playgroud)

此外,此 ENV 变量将在您的应用程序中可用。

  • 在conftest.py中,你甚至不必使用pytest_generate_tests;你可以简单地设置 os.environ 。 (11认同)

Eug*_*kin 17

可以使用自动装置

@pytest.fixture(scope="session", autouse=True)
def set_env():
    os.environ["FLAG"] = "1"
Run Code Online (Sandbox Code Playgroud)

  • 太棒了,这绝对是最优雅、最惯用的解决方案! (2认同)

Mia*_*Kim 13

  1. 当我不在函数外部加载环境变量变量时,我使用猴子补丁。
import os

# success.py
def hello_world():
    return os.environ["HELLO"]

# fail.py
global_ref = os.environ["HELLO"] # KeyError occurs this line because getting environment variable before monkeypatching

def hello_world():
    return global_ref

# test.py
def test_hello_world(monkeypatch):
    # Setup
    envs = {
        'HELLO': 'world'
    }
    monkeypatch.setattr(os, 'environ', envs)

    # Test
    result = hello_world()

    # Verify
    assert(result == 'world')
Run Code Online (Sandbox Code Playgroud)
  1. 如果你使用 PyCharm 你可以设置环境变量,[Run]-> [Edit Configuration]-> [Defaults]-> [py.tests]->[Environment Variables]

在此处输入图片说明


sri*_*249 11

我终于找到了我正在寻找的答案.

我们可以在使用py.test运行测试之前设置这样的环境变量

ENV_NAME ='staging'ENV_NUMBER ='5'py.test

  • 解决办法是什么,设置环境变量,设置环境变量。希望能有一个真正的解决方案…… (39认同)
  • 在您的问题中,您已经写过您不想对值进行硬编码,并且您已经接受了自己的解决方案,该解决方案正是这样做的? (5认同)
  • 以后怎么用? (2认同)

Mac*_*_89 10

你可以通过几种方法实现这一目标

1)如果您不想使用环境变量,可以使用pytest addoptions作为https://pytest.org/latest/example/simple.html

2)您可以编写这样的包装器脚本来调用环境变量

   import os
   import py
   env_name = os.environ["ENV_NAME"]
   env_no = os.environ["ENV_NUMBER"]
   pytest_args=(env_name,env_no)
   pytest.main('-s' ,pytest_args,test_file.py) 
Run Code Online (Sandbox Code Playgroud)

在test_file.py中你可以使用

   env_n, env_n = pytest.config.getoption('pytest_args')
Run Code Online (Sandbox Code Playgroud)

3)备用方法如果你只想传递日期未设置enviornment变量

在命令行上,您可以将其用作

   py.test --testdata ="ENV_NAME:staging,ENV_NUMBER:5"
Run Code Online (Sandbox Code Playgroud)

您可以在测试文件中使用

pytest_params = pytest.config.getoption('testdata')
params = pytest_params.split(":")
param_dict = dict(params[i:i+2] for i in range(0,len(params),2))
env_name = param_dict["ENV_Name"]
Run Code Online (Sandbox Code Playgroud)


sim*_*mno 8

在子 shell(括弧)内运行export,以免扰乱本地环境。提供.env文件中的参数导出。

(export $(xargs < .env); pytest -svvvx api)


pba*_*icz 6

遵循@tutuDajuju 提供的想法,使用pytest-env - 另一种方法是编写一个利用pytest_load_initial_conftests的自定义插件。可能很有用,尤其是当您不想或无法安装外部依赖项时。

这是一个快速示例:

项目结构

.
??? __init__.py
??? pytest.ini
??? script.py
??? tests
    ??? __init__.py
    ??? plugins
    ?   ??? __init__.py
    ?   ??? env_vars.py
    ??? test_script.py
Run Code Online (Sandbox Code Playgroud)

脚本文件

.
??? __init__.py
??? pytest.ini
??? script.py
??? tests
    ??? __init__.py
    ??? plugins
    ?   ??? __init__.py
    ?   ??? env_vars.py
    ??? test_script.py
Run Code Online (Sandbox Code Playgroud)

测试脚本.py

import os

FOOBAR = os.environ.get("FOOBAR")


def foobar():
    return FOOBAR
Run Code Online (Sandbox Code Playgroud)

pytest.ini

[pytest]
addopts = -p tests.plugins.env_vars
Run Code Online (Sandbox Code Playgroud)

env_vars.py

from script import foobar


def test_foobar():
    assert foobar() == "foobar"
Run Code Online (Sandbox Code Playgroud)

示例运行:

$ python -m pytest tests -v
========= test session starts =========
platform darwin -- Python 3.8.1, pytest-5.4.1, py-1.8.1, pluggy-0.13.1 -- 
rootdir: /Users/user/pytest_plugins, inifile: pytest.ini
collected 1 item

tests/test_script.py::test_foobar PASSED                                                                                               [100%]

========= 1 passed in 0.01s =========
Run Code Online (Sandbox Code Playgroud)


Q. *_*iao 6

类似于 bad_coder 提到的,你可以这样做:

# test.py
def test_hello_world(monkeypatch):
    # Setup
    monkeypatch.setenv('HELLO', 'world')

    # Test
    result = hello_world()

    # Verify
    assert(result == 'world')
Run Code Online (Sandbox Code Playgroud)

  • 完全看起来是正确的答案,但是,对我来说不起作用,而且我不明白为什么。 (3认同)