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
|
- fix issue91 - add/discuss package/directory level setups in example
|
||||||
- allow to dynamically define markers/keywords via
|
- allow to dynamically define markers via
|
||||||
item.keywords[...]=assignment
|
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
|
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 = []
|
remaining = []
|
||||||
deselected = []
|
deselected = []
|
||||||
for colitem in items:
|
for colitem in items:
|
||||||
if keywordexpr and skipbykeyword(colitem, keywordexpr):
|
if keywordexpr and not matchkeyword(colitem, keywordexpr):
|
||||||
deselected.append(colitem)
|
deselected.append(colitem)
|
||||||
else:
|
else:
|
||||||
if selectuntil:
|
if selectuntil:
|
||||||
|
@ -72,37 +72,26 @@ class BoolDict:
|
||||||
def __getitem__(self, name):
|
def __getitem__(self, name):
|
||||||
return name in self._mydict
|
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):
|
def matchmark(colitem, matchexpr):
|
||||||
return eval(matchexpr, {}, BoolDict(colitem.keywords))
|
return eval(matchexpr, {}, BoolDict(colitem.keywords))
|
||||||
|
|
||||||
|
def matchkeyword(colitem, keywordexpr):
|
||||||
|
keywordexpr = keywordexpr.replace("-", "not ")
|
||||||
|
return eval(keywordexpr, {}, SubstringDict(colitem.keywords))
|
||||||
|
|
||||||
def pytest_configure(config):
|
def pytest_configure(config):
|
||||||
if config.option.strict:
|
if config.option.strict:
|
||||||
pytest.mark._config = config
|
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:
|
class MarkGenerator:
|
||||||
""" Factory for :class:`MarkDecorator` objects - exposed as
|
""" Factory for :class:`MarkDecorator` objects - exposed as
|
||||||
a ``py.test.mark`` singleton instance. Example::
|
a ``py.test.mark`` singleton instance. Example::
|
||||||
|
|
2
setup.py
2
setup.py
|
@ -48,7 +48,7 @@ def main():
|
||||||
name='pytest',
|
name='pytest',
|
||||||
description='py.test: simple powerful testing with Python',
|
description='py.test: simple powerful testing with Python',
|
||||||
long_description = long_description,
|
long_description = long_description,
|
||||||
version='2.3.4.dev2',
|
version='2.3.4.dev3',
|
||||||
url='http://pytest.org',
|
url='http://pytest.org',
|
||||||
license='MIT license',
|
license='MIT license',
|
||||||
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
platforms=['unix', 'linux', 'osx', 'cygwin', 'win32'],
|
||||||
|
|
|
@ -162,6 +162,24 @@ def test_mark_option_custom(spec, testdir):
|
||||||
assert len(passed) == len(passed_result)
|
assert len(passed) == len(passed_result)
|
||||||
assert list(passed) == list(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:
|
class TestFunctional:
|
||||||
|
|
||||||
def test_mark_per_function(self, testdir):
|
def test_mark_per_function(self, testdir):
|
||||||
|
@ -366,11 +384,11 @@ class TestKeywordSelection:
|
||||||
for keyword in ['test_one', 'est_on']:
|
for keyword in ['test_one', 'est_on']:
|
||||||
#yield check, keyword, 'test_one'
|
#yield check, keyword, 'test_one'
|
||||||
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", [
|
@pytest.mark.parametrize("keyword", [
|
||||||
'xxx', 'xxx test_2', 'TestClass', 'xxx -test_1',
|
'xxx', 'xxx and test_2', 'TestClass', 'xxx and -test_1',
|
||||||
'TestClass test_2', 'xxx TestClass test_2'])
|
'TestClass and test_2', 'xxx and TestClass and test_2'])
|
||||||
def test_select_extra_keywords(self, testdir, keyword):
|
def test_select_extra_keywords(self, testdir, keyword):
|
||||||
p = testdir.makepyfile(test_select="""
|
p = testdir.makepyfile(test_select="""
|
||||||
def test_1():
|
def test_1():
|
||||||
|
|
Loading…
Reference in New Issue