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

Viewed 107

Imagine a toy test definition:

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

I now want to be able to provide bar on the command line. As far as I know this is not built into Py.Test yet:

pytest --param "bar=7"

And write my test parameter definition like this:

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

I can implement from_args_if_available() parsing all command line arguments again and looking for --params of course. Another way would be to make request.config available globally (which would be ugly).

I wonder if it's possible to access the request.config element from anywhere in order to have all command line option definition at one place (and thus the help).

So is there another way to access the parsed command line options which I can use in the described way?

1 Answers

I'll post my currently working solution here:

in a file utils.py I define a function 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

Which can be used like this:

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

A pytest call can look like this now:

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

in conftest.py I now have to add the param argument as well - otherwise an exception gets raised when I define parameters on command line:

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

Upside: it works :)

Downside: It's an ugly workaround, param() can't be defined inside conftest.py

Related