allow to pass expressions to "-k" option, just like with the "-m" option
This commit is contained in:
parent
a4909a0ae4
commit
4ac465acfb
|
@ -2,8 +2,13 @@ Changes between 2.3.3 and 2.3.4.dev
|
|||
-----------------------------------
|
||||
|
||||
- fix issue91 - add/discuss package/directory level setups in example
|
||||
- allow to dynamically define markers/keywords via
|
||||
item.keywords[...]=assignment
|
||||
- allow to dynamically define markers via
|
||||
item.keywords[...]=assignment integrating with "-m" option
|
||||
- make "-k" accept an expressions the same as with "-m" so that one
|
||||
can write: -k "name1 or name2" etc. This is a slight incompatibility
|
||||
if you used special syntax like "TestClass.test_method" which you now
|
||||
need to write as -k "TestClass and test_method" to match a certain
|
||||
method in a certain test class.
|
||||
|
||||
Changes between 2.3.2 and 2.3.3
|
||||
-----------------------------------
|
||||
|
|
|
@ -1,2 +1,2 @@
|
|||
#
|
||||
__version__ = '2.3.4.dev2'
|
||||
__version__ = '2.3.4.dev3'
|
||||
|
|
|
@ -51,7 +51,7 @@ def pytest_collection_modifyitems(items, config):
|
|||
remaining = []
|
||||
deselected = []
|
||||
for colitem in items:
|
||||
if keywordexpr and skipbykeyword(colitem, keywordexpr):
|
||||
if keywordexpr and not matchkeyword(colitem, keywordexpr):
|
||||
deselected.append(colitem)
|
||||
else:
|
||||
if selectuntil:
|
||||
|
@ -72,37 +72,26 @@ class BoolDict:
|
|||
def __getitem__(self, name):
|
||||
return name in self._mydict
|
||||
|
||||
class SubstringDict:
|
||||
def __init__(self, mydict):
|
||||
self._mydict = mydict
|
||||
def __getitem__(self, name):
|
||||
for key in self._mydict:
|
||||
if name in key:
|
||||
return True
|
||||
return False
|
||||
|
||||
def matchmark(colitem, matchexpr):
|
||||
return eval(matchexpr, {}, BoolDict(colitem.keywords))
|
||||
|
||||
def matchkeyword(colitem, keywordexpr):
|
||||
keywordexpr = keywordexpr.replace("-", "not ")
|
||||
return eval(keywordexpr, {}, SubstringDict(colitem.keywords))
|
||||
|
||||
def pytest_configure(config):
|
||||
if config.option.strict:
|
||||
pytest.mark._config = config
|
||||
|
||||
def skipbykeyword(colitem, keywordexpr):
|
||||
""" return True if they given keyword expression means to
|
||||
skip this collector/item.
|
||||
"""
|
||||
if not keywordexpr:
|
||||
return
|
||||
|
||||
itemkeywords = colitem.keywords
|
||||
for key in filter(None, keywordexpr.split()):
|
||||
eor = key[:1] == '-'
|
||||
if eor:
|
||||
key = key[1:]
|
||||
if not (eor ^ matchonekeyword(key, itemkeywords)):
|
||||
return True
|
||||
|
||||
def matchonekeyword(key, itemkeywords):
|
||||
for elem in key.split("."):
|
||||
for kw in itemkeywords:
|
||||
if elem in kw:
|
||||
break
|
||||
else:
|
||||
return False
|
||||
return True
|
||||
|
||||
class MarkGenerator:
|
||||
""" Factory for :class:`MarkDecorator` objects - exposed as
|
||||
a ``py.test.mark`` singleton instance. Example::
|
||||
|
|
2
setup.py
2
setup.py
|
@ -48,7 +48,7 @@ def main():
|
|||
name='pytest',
|
||||
description='py.test: simple powerful testing with Python',
|
||||
long_description = long_description,
|
||||
version='2.3.4.dev2',
|
||||
version='2.3.4.dev3',
|
||||
url='http://pytest.org',
|
||||
license='MIT license',
|
||||
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
||||
|
|
|
@ -162,6 +162,24 @@ def test_mark_option_custom(spec, testdir):
|
|||
assert len(passed) == len(passed_result)
|
||||
assert list(passed) == list(passed_result)
|
||||
|
||||
@pytest.mark.multi(spec=[
|
||||
("interface", ("test_interface",)),
|
||||
("not interface", ("test_nointer",)),
|
||||
])
|
||||
def test_keyword_option_custom(spec, testdir):
|
||||
testdir.makepyfile("""
|
||||
def test_interface():
|
||||
pass
|
||||
def test_nointer():
|
||||
pass
|
||||
""")
|
||||
opt, passed_result = spec
|
||||
rec = testdir.inline_run("-k", opt)
|
||||
passed, skipped, fail = rec.listoutcomes()
|
||||
passed = [x.nodeid.split("::")[-1] for x in passed]
|
||||
assert len(passed) == len(passed_result)
|
||||
assert list(passed) == list(passed_result)
|
||||
|
||||
class TestFunctional:
|
||||
|
||||
def test_mark_per_function(self, testdir):
|
||||
|
@ -366,11 +384,11 @@ class TestKeywordSelection:
|
|||
for keyword in ['test_one', 'est_on']:
|
||||
#yield check, keyword, 'test_one'
|
||||
check(keyword, 'test_one')
|
||||
check('TestClass.test', 'test_method_one')
|
||||
check('TestClass and test', 'test_method_one')
|
||||
|
||||
@pytest.mark.parametrize("keyword", [
|
||||
'xxx', 'xxx test_2', 'TestClass', 'xxx -test_1',
|
||||
'TestClass test_2', 'xxx TestClass test_2'])
|
||||
'xxx', 'xxx and test_2', 'TestClass', 'xxx and -test_1',
|
||||
'TestClass and test_2', 'xxx and TestClass and test_2'])
|
||||
def test_select_extra_keywords(self, testdir, keyword):
|
||||
p = testdir.makepyfile(test_select="""
|
||||
def test_1():
|
||||
|
|
Loading…
Reference in New Issue