根据py.test中的参数跳过测试

时间:2015-07-15 17:22:35

标签: python pytest

我有一个session范围的测试夹具,它是参数化的,例如

@pytest.fixture(scope="session", params=["one", "two", "three"])
def myfixture():
    ...

在我的目录中,我有使用pytest.mark.usefixtures("myfixture")的文件,一个包含测试的文件应仅针对myfixture "two"参数运行,而py.test应该跳过它。< / p>

有没有办法在py.test中实现这一点,还是需要在myfixture()函数的某个类中设置一个特殊变量?

4 个答案:

答案 0 :(得分:12)

我自己找到解决方案,可以在conftest.py中定义函数:

def pytest_namespace():
    return {"param": None}

在夹具功能中我们可以做到:

@pytest.fixture(scope="session", params=["one", "two", "three"])
def myfixture():
    pytest.param = request.param
    # ...

所以我们可以用以下方法包装测试类:

@pytest.mark.skipif("pytest.param == 'value'")
class TestSmth(object):
    ...

答案 1 :(得分:0)

我在尝试解决类似的用例时遇到了这个问题。我的解决方案可以帮助任何人避免几个小时。这是一种从测试中覆盖夹具参数化的简单方法:

@pytest.fixture(scope="session", params=["one", "two", "three"])
def myfixture():
    ...

@pytest.mark.parameterize('myfixture', ['two'], indirect=True)
def test1(myfixture):
    ...

def test2(myfixture):
    ...

感谢https://hackebrot.github.io/pytest-tricks/mark_parametrize_with_indirect/解释了间接方法的使用!

答案 2 :(得分:0)

执行此操作的干净方法是使用pytest_collection_modifyitems钩子在运行测试集合之前对其进行修改

按照以下说明获得灯具:

@pytest.fixture(scope="session", params=["one", "two", "three"])
def myfixture(request):
    ...

在测试中添加自定义标记:

@pytest.mark.restriction("two")
def test_smth(self, myfixture):
    ...

然后使用自定义取消选择逻辑修改测试集合:

def pytest_collection_modifyitems(items, config):
    """ deselect test items which do not match the fixture restriction """
    deselection_items = []
    for item in items:
        # There may be a better way than regex to get the parameter
        passed_param = re.search(r'\[(.+?)\]', item.name).group(1)
        restrictions = set([mark.args[0] for mark in item.iter_markers(name='restriction')])
        if len(restrictions) > 0:
            if passed_param not in restrictions:
                deselection_items.append(item)
    items[:] = [item for item in items if item not in deselection_items]
    config.hook.pytest_deselected(items=deselection_items)

答案 3 :(得分:0)

我最终写出了自己的装饰器,我认为它是相当容易和干净的:

import functools

def skip_targets(excluded_values):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            paramA = kwargs['paramA']
            if paramA in excluded_values:
                pytest.skip('Param A "{}" currently not supported'.format(paramA))
            func(*args, **kwargs)
        return wrapper
    return decorator

要停用针对paramA使用夹具的测试,可以像这样排除值X

@skip_targets(['X'])
def test_param(self, paramA):
    pass