我有一个session
范围的测试夹具,它是参数化的,例如
@pytest.fixture(scope="session", params=["one", "two", "three"])
def myfixture():
...
在我的目录中,我有使用pytest.mark.usefixtures("myfixture")
的文件,一个包含测试的文件应仅针对myfixture
"two"
参数运行,而py.test应该跳过它。< / p>
有没有办法在py.test中实现这一点,还是需要在myfixture()
函数的某个类中设置一个特殊变量?
答案 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