It is possible to do this, although depending on exactly what you want, it might take some work.
If you just need to skip specific parameter sets (i.e. if you don't need to use an expression to identify which parameter sets to skip), it's pretty easy:
@pytest.mark.parametrize("a", [
1,
pytest.param(2, marks=[pytest.mark.skip]),
])
def test_a(a):
assert a == 1
If you do need to use an expression, then I think the best approach is to write a custom pytest_runtest_setup
hook. This hook has access to the marks and parameters for each test, so it's a good place to implement the kind of logic you want. The basic idea is to get the skip condition from a custom mark, evaluate that condition in the context of the parameters, then skip based on the result:
# conftest.py
import pytest
def pytest_runtest_setup(item):
skip_funcs = [
mark.args[0]
for mark in item.iter_markers(name='parametrize_skip_if')
]
if any(f(**item.callspec.params) for f in skip_funcs):
pytest.skip()
# test_file.py
@pytest.mark.parametrize("b", [1, 2])
@pytest.mark.parametrize_skip_if(lambda b: b == 2)
def test_b(b):
assert b == 1