From 05155e4db0460cc58befbfd4af8192ef1ea14a88 Mon Sep 17 00:00:00 2001 From: Andrea Cimatoribus Date: Wed, 12 Sep 2018 12:04:45 +0200 Subject: [PATCH] Fail at parametrize option for empty parameter set Optionally raise an exception when parametrize collects no arguments. Provide the name of the test causing the failure in the exception message. See: #3849 --- src/_pytest/mark/__init__.py | 4 ++-- src/_pytest/mark/structures.py | 8 +++++++ testing/test_mark.py | 39 ++++++++++++++++++++++++++++++++-- 3 files changed, 47 insertions(+), 4 deletions(-) diff --git a/src/_pytest/mark/__init__.py b/src/_pytest/mark/__init__.py index e3918ca6a..eb25cd4aa 100644 --- a/src/_pytest/mark/__init__.py +++ b/src/_pytest/mark/__init__.py @@ -163,9 +163,9 @@ def pytest_configure(config): empty_parameterset = config.getini(EMPTY_PARAMETERSET_OPTION) - if empty_parameterset not in ("skip", "xfail", None, ""): + if empty_parameterset not in ("skip", "xfail", "fail_at_collect", None, ""): raise UsageError( - "{!s} must be one of skip and xfail," + "{!s} must be one of skip, xfail or fail_at_collect" " but it is {!r}".format(EMPTY_PARAMETERSET_OPTION, empty_parameterset) ) diff --git a/src/_pytest/mark/structures.py b/src/_pytest/mark/structures.py index 8e8937d59..2c4635bf4 100644 --- a/src/_pytest/mark/structures.py +++ b/src/_pytest/mark/structures.py @@ -32,11 +32,19 @@ def istestfunc(func): def get_empty_parameterset_mark(config, argnames, func): + from ..nodes import Collector + requested_mark = config.getini(EMPTY_PARAMETERSET_OPTION) if requested_mark in ("", None, "skip"): mark = MARK_GEN.skip elif requested_mark == "xfail": mark = MARK_GEN.xfail(run=False) + elif requested_mark == "fail_at_collect": + f_name = func.__name__ + _, lineno = getfslineno(func) + raise Collector.CollectError( + "Empty parameter set in '%s' at line %d" % (f_name, lineno) + ) else: raise LookupError(requested_mark) fs, lineno = getfslineno(func) diff --git a/testing/test_mark.py b/testing/test_mark.py index 9dad7a165..baf1d6f40 100644 --- a/testing/test_mark.py +++ b/testing/test_mark.py @@ -13,7 +13,7 @@ from _pytest.mark import ( transfer_markers, EMPTY_PARAMETERSET_OPTION, ) -from _pytest.nodes import Node +from _pytest.nodes import Node, Collector ignore_markinfo = pytest.mark.filterwarnings( "ignore:MarkInfo objects:pytest.RemovedInPytest4Warning" @@ -1091,7 +1091,14 @@ class TestMarkDecorator(object): @pytest.mark.parametrize("mark", [None, "", "skip", "xfail"]) def test_parameterset_for_parametrize_marks(testdir, mark): if mark is not None: - testdir.makeini("[pytest]\n{}={}".format(EMPTY_PARAMETERSET_OPTION, mark)) + testdir.makeini( + """ + [pytest] + {}={} + """.format( + EMPTY_PARAMETERSET_OPTION, mark + ) + ) config = testdir.parseconfig() from _pytest.mark import pytest_configure, get_empty_parameterset_mark @@ -1107,6 +1114,34 @@ def test_parameterset_for_parametrize_marks(testdir, mark): assert result_mark.kwargs.get("run") is False +def test_parameterset_for_fail_at_collect(testdir): + testdir.makeini( + """ + [pytest] + {}=fail_at_collect + """.format( + EMPTY_PARAMETERSET_OPTION + ) + ) + + config = testdir.parseconfig() + from _pytest.mark import pytest_configure, get_empty_parameterset_mark + from _pytest.compat import getfslineno + + pytest_configure(config) + + test_func = all + func_name = test_func.__name__ + _, func_lineno = getfslineno(test_func) + expected_errmsg = r"Empty parameter set in '%s' at line %d" % ( + func_name, + func_lineno, + ) + + with pytest.raises(Collector.CollectError, match=expected_errmsg): + get_empty_parameterset_mark(config, ["a"], test_func) + + def test_parameterset_for_parametrize_bad_markname(testdir): with pytest.raises(pytest.UsageError): test_parameterset_for_parametrize_marks(testdir, "bad")