Merge pull request #3442 from RonnyPfannschmidt/fix-3441-markexpr-markstorage
Fix #3441 let mark expressions be populated from the modern marker storage
This commit is contained in:
commit
35f53a7353
|
@ -5,8 +5,6 @@ we hope ot remove
|
||||||
import attr
|
import attr
|
||||||
import keyword
|
import keyword
|
||||||
|
|
||||||
from . import MarkInfo, MarkDecorator
|
|
||||||
|
|
||||||
from _pytest.config import UsageError
|
from _pytest.config import UsageError
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,11 +16,8 @@ class MarkMapping(object):
|
||||||
own_mark_names = attr.ib()
|
own_mark_names = attr.ib()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def from_keywords(cls, keywords):
|
def from_item(cls, item):
|
||||||
mark_names = set()
|
mark_names = set(mark.name for mark in item.iter_markers())
|
||||||
for key, value in keywords.items():
|
|
||||||
if isinstance(value, MarkInfo) or isinstance(value, MarkDecorator):
|
|
||||||
mark_names.add(key)
|
|
||||||
return cls(mark_names)
|
return cls(mark_names)
|
||||||
|
|
||||||
def __getitem__(self, name):
|
def __getitem__(self, name):
|
||||||
|
@ -70,7 +65,7 @@ python_keywords_allowed_list = ["or", "and", "not"]
|
||||||
|
|
||||||
def matchmark(colitem, markexpr):
|
def matchmark(colitem, markexpr):
|
||||||
"""Tries to match on any marker names, attached to the given colitem."""
|
"""Tries to match on any marker names, attached to the given colitem."""
|
||||||
return eval(markexpr, {}, MarkMapping.from_keywords(colitem.keywords))
|
return eval(markexpr, {}, MarkMapping.from_item(colitem))
|
||||||
|
|
||||||
|
|
||||||
def matchkeyword(colitem, keywordexpr):
|
def matchkeyword(colitem, keywordexpr):
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Also use iter_marker for discovering the marks applying for marker expressions from the cli to avoid the bad data from the legacy mark storage.
|
|
@ -295,7 +295,7 @@ def test_mark_option_custom(spec, testdir):
|
||||||
def pytest_collection_modifyitems(items):
|
def pytest_collection_modifyitems(items):
|
||||||
for item in items:
|
for item in items:
|
||||||
if "interface" in item.nodeid:
|
if "interface" in item.nodeid:
|
||||||
item.keywords["interface"] = pytest.mark.interface
|
item.add_marker(pytest.mark.interface)
|
||||||
""")
|
""")
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
def test_interface():
|
def test_interface():
|
||||||
|
@ -927,3 +927,35 @@ def test_parameterset_for_parametrize_marks(testdir, mark):
|
||||||
def test_parameterset_for_parametrize_bad_markname(testdir):
|
def test_parameterset_for_parametrize_bad_markname(testdir):
|
||||||
with pytest.raises(pytest.UsageError):
|
with pytest.raises(pytest.UsageError):
|
||||||
test_parameterset_for_parametrize_marks(testdir, 'bad')
|
test_parameterset_for_parametrize_marks(testdir, 'bad')
|
||||||
|
|
||||||
|
|
||||||
|
def test_mark_expressions_no_smear(testdir):
|
||||||
|
testdir.makepyfile("""
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
class BaseTests(object):
|
||||||
|
def test_something(self):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@pytest.mark.FOO
|
||||||
|
class TestFooClass(BaseTests):
|
||||||
|
pass
|
||||||
|
|
||||||
|
@pytest.mark.BAR
|
||||||
|
class TestBarClass(BaseTests):
|
||||||
|
pass
|
||||||
|
""")
|
||||||
|
|
||||||
|
reprec = testdir.inline_run("-m", 'FOO')
|
||||||
|
passed, skipped, failed = reprec.countoutcomes()
|
||||||
|
dlist = reprec.getcalls("pytest_deselected")
|
||||||
|
assert passed == 1
|
||||||
|
assert skipped == failed == 0
|
||||||
|
deselected_tests = dlist[0].items
|
||||||
|
assert len(deselected_tests) == 1
|
||||||
|
|
||||||
|
# keywords smear - expected behaviour
|
||||||
|
reprec_keywords = testdir.inline_run("-k", 'FOO')
|
||||||
|
passed_k, skipped_k, failed_k = reprec_keywords.countoutcomes()
|
||||||
|
assert passed_k == 2
|
||||||
|
assert skipped_k == failed_k == 0
|
||||||
|
|
Loading…
Reference in New Issue