将命令行参数作为参数传递给 py.test fixture

Passing a command line argument to a py.test fixture as a parameter

诚然,这不是最好的开始方式,更重要的是,夹具参数已解决,即 Options.get_option() 在其他所有事情之前被调用。 建议和建议将不胜感激。

来自config.py

class Options(object):
    option = None

    @classmethod
    def get_option(cls):
        return cls.option

来自conftest.py

@pytest.yield_fixture(scope='session', autouse=True)
def session_setup():
    Options.option = pytest.config.getoption('--remote')

def pytest_addoption(parser):
    parser.addoption("--remote", action="store_true", default=False, help="Runs tests on a remote service.")




@pytest.yield_fixture(scope='function', params=Options.get_option())
def setup(request):
    if request.param is None:
        raise Exception("option is none")

不要使用自定义 Options class 而是直接从配置中请求选项。

pytest_generate_tests 可用于参数化类似夹具的参数以进行测试。

conftest.py

def pytest_addoption(parser):
    parser.addoption("--pg_tag", action="append", default=[],
                     help=("Postgres server versions. "
                           "May be used several times. "
                           "Available values: 9.3, 9.4, 9.5, all"))

def pytest_generate_tests(metafunc):
    if 'pg_tag' in metafunc.fixturenames:
        tags = set(metafunc.config.option.pg_tag)
        if not tags:
            tags = ['9.5']
        elif 'all' in tags:
            tags = ['9.3', '9.4', '9.5']
        else:
            tags = list(tags)
        metafunc.parametrize("pg_tag", tags, scope='session')

@pytest.yield_fixture(scope='session')
def pg_server(pg_tag):
    # pg_tag is parametrized parameter
    # the fixture is called 1-3 times depending on --pg_tag cmdline

编辑:将旧示例替换为 metafunc.parametrize 用法。

最新文档中有一个关于如何执行此操作的示例。它有点被埋没了,老实说,我第一次阅读文档时就对它上了釉:https://docs.pytest.org/en/latest/parametrize.html#basic-pytest-generate-tests-example.

Basic pytest_generate_tests example

Sometimes you may want to implement your own parametrization scheme or implement some dynamism for determining the parameters or scope of a fixture. For this, you can use the pytest_generate_tests hook which is called when collecting a test function. Through the passed in metafunc object you can inspect the requesting test context and, most importantly, you can call metafunc.parametrize() to cause parametrization.

For example, let’s say we want to run a test taking string inputs which we want to set via a new pytest command line option. Let’s first write a simple test accepting a stringinput fixture function argument:

# content of test_strings.py

def test_valid_string(stringinput):
    assert stringinput.isalpha()

Now we add a conftest.py file containing the addition of a command line option and the parametrization of our test function:

# content of conftest.py

def pytest_addoption(parser):
    parser.addoption("--stringinput", action="append", default=[],
        help="list of stringinputs to pass to test functions")

def pytest_generate_tests(metafunc):
    if 'stringinput' in metafunc.fixturenames:
        metafunc.parametrize("stringinput",
                             metafunc.config.getoption('stringinput'))

If we now pass two stringinput values, our test will run twice:

$ pytest -q --stringinput="hello" --stringinput="world" test_strings.py`
..
2 passed in 0.12 seconds