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

10

承认起始方式并不是最好的方法,更重要的是在解决装置参数之前,即在调用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")
2个回答

11

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

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替换了旧示例。


尽管我很想避免使用该类来自动生成测试参数并针对每个参数运行所有测试,但我还是需要使用它。 - mehmetg
现在我理解了您的需求。请看下面的重写示例,它使用 pytest_generate_testsmetafunc.parametrize 来添加参数化参数。 - Andrew Svetlov
这个例子应该在文档中。我已经使用了所有的部分,但没有想到这种组合。谢谢。 - mehmetg
我不是pytest的贡献者,但如果你想向文档提交Pull Request,那么欢迎,当然。 - Andrew Svetlov

4
最新文档中有一个关于如何执行此操作的示例。它有点难以找到,老实说,第一次阅读文档时我也忽略了它: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

请在此处复制有关内容。链接可以删除或更改。请注意,我只能提供文本翻译,无法处理图像或其他非文本形式的内容。 - GGO

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接