feature: default behavior now is to ignore duplicate paths specified from the command line. Use --keep-duplicates to retain duplicate paths.
This commit is contained in:
parent
a24146dd3c
commit
ab6aef1d1f
1
AUTHORS
1
AUTHORS
|
@ -95,6 +95,7 @@ Punyashloka Biswal
|
||||||
Quentin Pradet
|
Quentin Pradet
|
||||||
Ralf Schmitt
|
Ralf Schmitt
|
||||||
Raphael Pierzina
|
Raphael Pierzina
|
||||||
|
Roberto Polli
|
||||||
Romain Dorgueil
|
Romain Dorgueil
|
||||||
Roman Bolshakov
|
Roman Bolshakov
|
||||||
Ronny Pfannschmidt
|
Ronny Pfannschmidt
|
||||||
|
|
|
@ -120,8 +120,11 @@ time or change existing behaviors in order to make them less surprising/more use
|
||||||
fixtures and reports them;
|
fixtures and reports them;
|
||||||
+ ``--setup-show``: performs normal test execution and additionally shows
|
+ ``--setup-show``: performs normal test execution and additionally shows
|
||||||
setup and teardown of fixtures;
|
setup and teardown of fixtures;
|
||||||
|
+ ``--keep-duplicates``: default behavior is now to ignore duplicate paths, you can
|
||||||
|
retain the old behavior and running multiple times the tests
|
||||||
|
using the ``--keep-duplicates`` cli argument `#1609`_;
|
||||||
|
|
||||||
Thanks `@d6e`_, `@kvas-it`_, `@sallner`_ and `@omarkohl`_ for the PRs.
|
Thanks `@d6e`_, `@kvas-it`_, `@sallner`_, `@ioggstream`_ and `@omarkohl`_ for the PRs.
|
||||||
|
|
||||||
* New CLI flag ``--override-ini``/``-o``: overrides values from the ini file.
|
* New CLI flag ``--override-ini``/``-o``: overrides values from the ini file.
|
||||||
For example: ``"-o xfail_strict=True"``'.
|
For example: ``"-o xfail_strict=True"``'.
|
||||||
|
@ -524,6 +527,7 @@ time or change existing behaviors in order to make them less surprising/more use
|
||||||
|
|
||||||
.. _`traceback style docs`: https://pytest.org/latest/usage.html#modifying-python-traceback-printing
|
.. _`traceback style docs`: https://pytest.org/latest/usage.html#modifying-python-traceback-printing
|
||||||
|
|
||||||
|
.. _#1609: https://github.com/pytest-dev/pytest/issues/1609
|
||||||
.. _#1422: https://github.com/pytest-dev/pytest/issues/1422
|
.. _#1422: https://github.com/pytest-dev/pytest/issues/1422
|
||||||
.. _#1379: https://github.com/pytest-dev/pytest/issues/1379
|
.. _#1379: https://github.com/pytest-dev/pytest/issues/1379
|
||||||
.. _#1366: https://github.com/pytest-dev/pytest/issues/1366
|
.. _#1366: https://github.com/pytest-dev/pytest/issues/1366
|
||||||
|
@ -549,6 +553,7 @@ time or change existing behaviors in order to make them less surprising/more use
|
||||||
.. _@rabbbit: https://github.com/rabbbit
|
.. _@rabbbit: https://github.com/rabbbit
|
||||||
.. _@hackebrot: https://github.com/hackebrot
|
.. _@hackebrot: https://github.com/hackebrot
|
||||||
.. _@pquentin: https://github.com/pquentin
|
.. _@pquentin: https://github.com/pquentin
|
||||||
|
.. _@ioggstream: https://github.com/ioggstream
|
||||||
|
|
||||||
2.8.7
|
2.8.7
|
||||||
=====
|
=====
|
||||||
|
|
|
@ -155,6 +155,7 @@ class PytestPluginManager(PluginManager):
|
||||||
self._conftestpath2mod = {}
|
self._conftestpath2mod = {}
|
||||||
self._confcutdir = None
|
self._confcutdir = None
|
||||||
self._noconftest = False
|
self._noconftest = False
|
||||||
|
self._duplicatepaths = set()
|
||||||
|
|
||||||
self.add_hookspecs(_pytest.hookspec)
|
self.add_hookspecs(_pytest.hookspec)
|
||||||
self.register(self)
|
self.register(self)
|
||||||
|
|
|
@ -63,6 +63,9 @@ def pytest_addoption(parser):
|
||||||
group.addoption('--noconftest', action="store_true",
|
group.addoption('--noconftest', action="store_true",
|
||||||
dest="noconftest", default=False,
|
dest="noconftest", default=False,
|
||||||
help="Don't load any conftest.py files.")
|
help="Don't load any conftest.py files.")
|
||||||
|
group.addoption('--keepduplicates', '--keep-duplicates', action="store_true",
|
||||||
|
dest="keepduplicates", default=False,
|
||||||
|
help="Skip duplicate tests.")
|
||||||
|
|
||||||
group = parser.getgroup("debugconfig",
|
group = parser.getgroup("debugconfig",
|
||||||
"test session debugging and configuration")
|
"test session debugging and configuration")
|
||||||
|
@ -154,7 +157,25 @@ def pytest_ignore_collect(path, config):
|
||||||
excludeopt = config.getoption("ignore")
|
excludeopt = config.getoption("ignore")
|
||||||
if excludeopt:
|
if excludeopt:
|
||||||
ignore_paths.extend([py.path.local(x) for x in excludeopt])
|
ignore_paths.extend([py.path.local(x) for x in excludeopt])
|
||||||
return path in ignore_paths
|
|
||||||
|
if path in ignore_paths:
|
||||||
|
return True
|
||||||
|
|
||||||
|
# Skip duplicate paths.
|
||||||
|
# TODO: is this called when specifying direct filenames
|
||||||
|
# from command lines, eg.
|
||||||
|
# py.test test_a.py test_b.py
|
||||||
|
keepduplicates = config.getoption("keepduplicates")
|
||||||
|
duplicate_paths = config.pluginmanager._duplicatepaths
|
||||||
|
if not keepduplicates:
|
||||||
|
if path in duplicate_paths:
|
||||||
|
# TODO should we log this?
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
duplicate_paths.add(path)
|
||||||
|
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
class FSHookProxy:
|
class FSHookProxy:
|
||||||
def __init__(self, fspath, pm, remove_mods):
|
def __init__(self, fspath, pm, remove_mods):
|
||||||
|
|
|
@ -40,6 +40,40 @@ you will see that ``pytest`` only collects test-modules, which do not match the
|
||||||
======= 5 passed in 0.02 seconds =======
|
======= 5 passed in 0.02 seconds =======
|
||||||
|
|
||||||
|
|
||||||
|
Keeping duplicate paths specified from command line
|
||||||
|
----------------------------------------------------
|
||||||
|
|
||||||
|
Default behavior of ``pytest`` is to ignore duplicate paths specified from the command line.
|
||||||
|
Example::
|
||||||
|
|
||||||
|
py.test path_a path_a
|
||||||
|
|
||||||
|
...
|
||||||
|
collected 1 item
|
||||||
|
...
|
||||||
|
|
||||||
|
Just collect tests once.
|
||||||
|
|
||||||
|
To collect duplicate tests, use the ``--keep-duplicates`` option on the cli.
|
||||||
|
Example::
|
||||||
|
|
||||||
|
py.test --keep-duplicates path_a path_a
|
||||||
|
|
||||||
|
...
|
||||||
|
collected 2 items
|
||||||
|
...
|
||||||
|
|
||||||
|
As the collector just works on directories, if you specify twice a single test file, ``pytest`` will
|
||||||
|
still collect it twice, no matter if the ``--keep-duplicates`` is not specified.
|
||||||
|
Example::
|
||||||
|
|
||||||
|
py.test test_a.py test_a.py
|
||||||
|
|
||||||
|
...
|
||||||
|
collected 2 items
|
||||||
|
...
|
||||||
|
|
||||||
|
|
||||||
Changing directory recursion
|
Changing directory recursion
|
||||||
-----------------------------------------------------
|
-----------------------------------------------------
|
||||||
|
|
||||||
|
|
|
@ -1213,3 +1213,40 @@ def test_syntax_error_with_non_ascii_chars(testdir):
|
||||||
'*SyntaxError*',
|
'*SyntaxError*',
|
||||||
'*1 error in*',
|
'*1 error in*',
|
||||||
])
|
])
|
||||||
|
|
||||||
|
|
||||||
|
def test_skip_duplicates_by_default(testdir):
|
||||||
|
"""Test for issue https://github.com/pytest-dev/pytest/issues/1609 (#1609)
|
||||||
|
|
||||||
|
Ignore duplicate directories.
|
||||||
|
"""
|
||||||
|
a = testdir.mkdir("a")
|
||||||
|
fh = a.join("test_a.py")
|
||||||
|
fh.write(_pytest._code.Source("""
|
||||||
|
import pytest
|
||||||
|
def test_real():
|
||||||
|
pass
|
||||||
|
"""))
|
||||||
|
result = testdir.runpytest(a.strpath, a.strpath)
|
||||||
|
result.stdout.fnmatch_lines([
|
||||||
|
'*collected 1 item*',
|
||||||
|
])
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def test_keep_duplicates(testdir):
|
||||||
|
"""Test for issue https://github.com/pytest-dev/pytest/issues/1609 (#1609)
|
||||||
|
|
||||||
|
Use --keep-duplicates to collect tests from duplicate directories.
|
||||||
|
"""
|
||||||
|
a = testdir.mkdir("a")
|
||||||
|
fh = a.join("test_a.py")
|
||||||
|
fh.write(_pytest._code.Source("""
|
||||||
|
import pytest
|
||||||
|
def test_real():
|
||||||
|
pass
|
||||||
|
"""))
|
||||||
|
result = testdir.runpytest("--keep-duplicates", a.strpath, a.strpath)
|
||||||
|
result.stdout.fnmatch_lines([
|
||||||
|
'*collected 2 item*',
|
||||||
|
])
|
||||||
|
|
|
@ -973,7 +973,7 @@ class TestMetafuncFunctional:
|
||||||
"""))
|
"""))
|
||||||
sub1.join("test_in_sub1.py").write("def test_1(): pass")
|
sub1.join("test_in_sub1.py").write("def test_1(): pass")
|
||||||
sub2.join("test_in_sub2.py").write("def test_2(): pass")
|
sub2.join("test_in_sub2.py").write("def test_2(): pass")
|
||||||
result = testdir.runpytest("-v", "-s", sub1, sub2, sub1)
|
result = testdir.runpytest("--keep-duplicates", "-v", "-s", sub1, sub2, sub1)
|
||||||
result.assert_outcomes(passed=3)
|
result.assert_outcomes(passed=3)
|
||||||
|
|
||||||
def test_generate_same_function_names_issue403(self, testdir):
|
def test_generate_same_function_names_issue403(self, testdir):
|
||||||
|
|
Loading…
Reference in New Issue