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:
parent
663f824fc4
commit
08f3a0791d
|
@ -11,6 +11,13 @@ Unreleased
|
||||||
help with random "xdist" collection failures. Thanks to
|
help with random "xdist" collection failures. Thanks to
|
||||||
Ronny Pfannschmidt and Donald Stufft for helping to isolate it.
|
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
|
- fix issue384 by removing the trial support code
|
||||||
since the unittest compat enhancements allow
|
since the unittest compat enhancements allow
|
||||||
trial to handle it on its own
|
trial to handle it on its own
|
||||||
|
|
|
@ -140,7 +140,13 @@ def matchkeyword(colitem, keywordexpr):
|
||||||
for name in colitem.function.__dict__:
|
for name in colitem.function.__dict__:
|
||||||
mapped_names.add(name)
|
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):
|
def pytest_configure(config):
|
||||||
|
|
|
@ -95,6 +95,17 @@ Or to select "http" and "quick" tests::
|
||||||
================= 1 tests deselected by '-khttp or quick' ==================
|
================= 1 tests deselected by '-khttp or quick' ==================
|
||||||
================== 2 passed, 1 deselected in 0.01 seconds ==================
|
================== 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
|
Registering markers
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -174,7 +174,9 @@ def test_mark_option_custom(spec, testdir):
|
||||||
|
|
||||||
@pytest.mark.parametrize("spec", [
|
@pytest.mark.parametrize("spec", [
|
||||||
("interface", ("test_interface",)),
|
("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):
|
def test_keyword_option_custom(spec, testdir):
|
||||||
testdir.makepyfile("""
|
testdir.makepyfile("""
|
||||||
|
@ -182,6 +184,8 @@ def test_keyword_option_custom(spec, testdir):
|
||||||
pass
|
pass
|
||||||
def test_nointer():
|
def test_nointer():
|
||||||
pass
|
pass
|
||||||
|
def test_pass():
|
||||||
|
pass
|
||||||
""")
|
""")
|
||||||
opt, passed_result = spec
|
opt, passed_result = spec
|
||||||
rec = testdir.inline_run("-k", opt)
|
rec = testdir.inline_run("-k", opt)
|
||||||
|
@ -191,6 +195,24 @@ def test_keyword_option_custom(spec, testdir):
|
||||||
assert list(passed) == list(passed_result)
|
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:
|
class TestFunctional:
|
||||||
|
|
||||||
def test_mark_per_function(self, testdir):
|
def test_mark_per_function(self, testdir):
|
||||||
|
|
Loading…
Reference in New Issue