在 pytest 中是否可以在参数化装饰器中访问命令行参数?

In pytest is it possible to access command line arguments in parametrize decorators?

想象一个玩具测试定义:

@pytest.mark.parametrize("bar", [1, 2, 3])
def test_foo(bar):
    assert some_result(bar)

我现在希望能够在命令行上提供 bar。据我所知,这还没有内置到 Py.Test 中:

pytest --param "bar=7"

然后这样写我的测试参数定义:

@pytest.mark.parametrize(*from_args_if_available("bar", [1, 2, 3]))
def test_foo(bar):
    assert some_result(bar)

可以实现from_args_if_available()再次解析所有命令行参数并寻找--params当然。另一种方法是使 request.config 全局可用(这会很难看)。

我想知道是否可以从任何地方访问 request.config 元素,以便将所有命令行选项定义放在一个地方(以及帮助)。

那么有没有另一种方法来访问我可以按照描述的方式使用的已解析的命令行选项?

我将post我目前正在使用的解决方案:

在一个文件中utils.py我定义了一个函数param:

def param(name, default_value):
  parser = argparse.ArgumentParser()
  parser.add_argument("--param", action="store")
  args, unknown = parser.parse_known_args()
  try:
    if args.param:
      for p_name, p_value in (param.split("=") for param in args.param.split(";")):
        if p_name == name:
          return p_name, ast.literal_eval(p_value)
  except (SyntaxError, ValueError):
    raise RuntimeError(
      "Wrong parameter definition: %r, must be 'name1=<expr>;name2=<expr>;..'"
      % args.param)
  return name, default_value

可以这样使用:

import pytest
from util import param

@pytest.mark.parametrize(*param("bar", [1, 2, 3]))
def test_foo(bar, env_type):
  print("param: ", "bar", bar)
  assert bar < 7

pytest 调用现在看起来像这样:

pytest --param "bar=[5,6,7];unused=range(5)"

conftest.py 我现在还必须添加 param 参数 - 否则当我在命令行上定义参数时会引发异常:

def pytest_addoption(parser):
  parser.addoption("--param", action="store", help="overwrite test parameters")

好处:有效:)

缺点:这是一个丑陋的解决方法,param() 无法在 conftest.py

中定义