fix issue357 - special case "-k" expressions to allow for

filtering with simple strings that are not valid python expressions.
Examples: "-k 1.3" matches all tests parametrized with 1.3.
"-k None" filters all tests that have "None" in their name
and conversely "-k 'not None'".
Previously these examples would raise syntax errors.

Also add a note to the docs about what is allowed.
This commit is contained in:
holger krekel 2013-11-21 15:25:16 +01:00
parent 663f824fc4
commit 08f3a0791d
4 changed files with 48 additions and 2 deletions

View File

@ -11,6 +11,13 @@ Unreleased
help with random "xdist" collection failures. Thanks to
Ronny Pfannschmidt and Donald Stufft for helping to isolate it.
- fix issue357 - special case "-k" expressions to allow for
filtering with simple strings that are not valid python expressions.
Examples: "-k 1.3" matches all tests parametrized with 1.3.
"-k None" filters all tests that have "None" in their name
and conversely "-k 'not None'".
Previously these examples would raise syntax errors.
- fix issue384 by removing the trial support code
since the unittest compat enhancements allow
trial to handle it on its own

View File

@ -140,7 +140,13 @@ def matchkeyword(colitem, keywordexpr):
for name in colitem.function.__dict__:
mapped_names.add(name)
return eval(keywordexpr, {}, KeywordMapping(mapped_names))
mapping = KeywordMapping(mapped_names)
if " " not in keywordexpr:
# special case to allow for simple "-k pass" and "-k 1.3"
return mapping[keywordexpr]
elif keywordexpr.startswith("not ") and " " not in keywordexpr[4:]:
return not mapping[keywordexpr[4:]]
return eval(keywordexpr, {}, mapping)
def pytest_configure(config):

View File

@ -95,6 +95,17 @@ Or to select "http" and "quick" tests::
================= 1 tests deselected by '-khttp or quick' ==================
================== 2 passed, 1 deselected in 0.01 seconds ==================
.. note::
If you are using expressions such as "X and Y" then both X and Y
need to be simple non-keyword names. For example, "pass" or "from"
will result in SyntaxErrors because "-k" evaluates the expression.
However, if the "-k" argument is a simple string, no such restrictions
apply. Also "-k 'not STRING'" has no restrictions. You can also
specify numbers like "-k 1.3" to match tests which are parametrized
with the float "1.3".
Registering markers
-------------------------------------

View File

@ -174,7 +174,9 @@ def test_mark_option_custom(spec, testdir):
@pytest.mark.parametrize("spec", [
("interface", ("test_interface",)),
("not interface", ("test_nointer",)),
("not interface", ("test_nointer", "test_pass")),
("pass", ("test_pass",)),
("not pass", ("test_interface", "test_nointer")),
])
def test_keyword_option_custom(spec, testdir):
testdir.makepyfile("""
@ -182,6 +184,8 @@ def test_keyword_option_custom(spec, testdir):
pass
def test_nointer():
pass
def test_pass():
pass
""")
opt, passed_result = spec
rec = testdir.inline_run("-k", opt)
@ -191,6 +195,24 @@ def test_keyword_option_custom(spec, testdir):
assert list(passed) == list(passed_result)
@pytest.mark.parametrize("spec", [
("None", ("test_func[None]",)),
("1.3", ("test_func[1.3]",))
])
def test_keyword_option_parametrize(spec, testdir):
testdir.makepyfile("""
import pytest
@pytest.mark.parametrize("arg", [None, 1.3])
def test_func(arg):
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):