使用 pytest 获取命令行参数并将其分配给全局变量

Fetch command line argument and assign it to global variable using pytest

必须使用 pytest 获取命令行参数并将它们分配给非测试模块下 python 脚本中的全局变量。

示例代码:

# conftest.py
def pytest_addoption(parser):
    parser.addoption("--name", action="store", default="default name")
# test_sample.py
import pytest

@pytest.fixture
def name(req):
    return req.getoption("name")

# Here, I require the command line argument assigned to a global variable "glob_name"
glob_name = name

foo="""
def test_"""+glob_name+"""():
    print("Inside test function with a global name")
"""
exec(foo)

使用的命令:

pytest -q -s test_sample.py --name google

发生错误:

========================================================================================== ERRORS ==========================================================================================
_____________________________________________________________________________ ERROR collecting test_sample.py ______________________________________________________________________________
test_sample.py:10: in <module>
    def test_"""+glob_name+"""():
E   TypeError: cannot concatenate 'str' and 'function' objects
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
1 error in 0.12 seconds

预期输出:

It should have to append the str "google" to the test function name and have to execute that function.

如果有人能回复上述问题的解决方案,我将不胜感激。

要实现您的要求,我们需要同时使用两个钩子。

  1. pytest_generate_tests : 实现你自己的参数化方案。
  2. pytest_collection_modifyitems : 根据您的要求重命名。

您可以使用下面的代码实现相同的效果

conftest.py

import pytest


def pytest_addoption(parser):
    parser.addoption("--name", action="store", default="default name")


@pytest.fixture(scope='session')
def get_name(request):
    return request.config.getoption("--name")


def pytest_generate_tests(metafunc):
    if "get_name" in metafunc.fixturenames:
        if metafunc.config.getoption("name"):
            param = str(metafunc.config.getoption("name"))
        else:
            param = "default"
        metafunc.parametrize("get_name", [param])


def pytest_collection_modifyitems(items):
    for item in items:
        # check that we are altering a test named `test_run_name`
        # and it accepts the `get_name` arg
        if item.originalname == 'test_run_name' and 'get_name' in item.fixturenames:
            item._nodeid = item.nodeid.replace(']', '').replace('run_name[', '')

test_sample.py

def test_run_name(get_name):
    print("Inside test function with a global name {}".format(get_name))
    assert True

运行 使用 cmd

pytest -v -s test_sample.py --name google

控制台输出: