allow to pass expressions to "-k" option, just like with the "-m" option

This commit is contained in:
holger krekel 2012-11-09 12:29:33 +01:00
parent a4909a0ae4
commit 4ac465acfb
5 changed files with 44 additions and 32 deletions

View File

@ -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
-----------------------------------

View File

@ -1,2 +1,2 @@
#
__version__ = '2.3.4.dev2'
__version__ = '2.3.4.dev3'

View File

@ -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::

View File

@ -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'],

View File

@ -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():