diff --git a/_pytest/mark.py b/_pytest/mark.py index 35cb3224a..24bb55838 100644 --- a/_pytest/mark.py +++ b/_pytest/mark.py @@ -95,11 +95,17 @@ class ParameterSet(namedtuple('ParameterSet', 'values, marks, id')): def get_empty_parameterset_mark(config, argnames, function): - + requested_mark = config.getini('empty_parameterset') + if requested_mark in ('', None, 'skip'): + mark = MARK_GEN.skip + elif requested_mark == 'xfail': + mark = MARK_GEN.xfail(run=False) + else: + raise LookupError(requested_mark) fs, lineno = getfslineno(function) reason = "got empty parameter set %r, function %s at %s:%d" % ( argnames, function.__name__, fs, lineno) - return MARK_GEN.skip(reason=reason) + return mark(reason=reason) class MarkerError(Exception): @@ -141,6 +147,9 @@ def pytest_addoption(parser): ) parser.addini("markers", "markers for test functions", 'linelist') + parser.addini( + "empty_parameterset", + "default marker for empty parametersets") def pytest_cmdline_main(config): @@ -284,6 +293,14 @@ def pytest_configure(config): if config.option.strict: MARK_GEN._config = config + empty_parameterset = config.getini("empty_parameterset") + + if empty_parameterset not in ('skip', 'xfail', None, ''): + from pytest import UsageError + raise UsageError( + "empty_parameterset must be one of skip and xfail," + " but it is {!r}".format(empty_parameterset)) + def pytest_unconfigure(config): MARK_GEN._config = getattr(config, '_old_mark_config', None) diff --git a/changelog/2527.feature b/changelog/2527.feature new file mode 100644 index 000000000..97e2a63fb --- /dev/null +++ b/changelog/2527.feature @@ -0,0 +1 @@ +introduce a pytest ini option to pick the mark for empty parametersets and allow to use xfail(run=False) \ No newline at end of file diff --git a/testing/test_mark.py b/testing/test_mark.py index 45e88ae8f..1e601fc44 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -891,3 +891,26 @@ class TestMarkDecorator(object): ]) def test__eq__(self, lhs, rhs, expected): assert (lhs == rhs) == expected + + +@pytest.mark.parametrize('mark', [None, 'skip', 'xfail']) +def test_parameterset_for_parametrize_marks(testdir, mark): + if mark is not None: + testdir.makeini("[pytest]\nempty_parameterset=" + mark) + + config = testdir.parseconfig() + from _pytest.mark import pytest_configure, get_empty_parameterset_mark + pytest_configure(config) + result_mark = get_empty_parameterset_mark(config, ['a'], all) + if mark is None: + # normalize to the requested name + mark = 'skip' + assert result_mark.name == mark + + if mark == 'xfail': + assert result_mark.kwargs.get('run') is False + + +def test_parameterset_for_parametrize_bad_markname(testdir): + with pytest.raises(pytest.UsageError): + test_parameterset_for_parametrize_marks(testdir, 'bad')