Skip to content

Commit fc8800c

Browse files
authored
Merge pull request #4722 from fetzerch/ignore_wildcards
Add ability to use globs when using --ignore
2 parents a131cd6 + 1876a92 commit fc8800c

File tree

7 files changed

+103
-0
lines changed

7 files changed

+103
-0
lines changed

AUTHORS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,7 @@ Charles Cloud
5151
Charnjit SiNGH (CCSJ)
5252
Chris Lamb
5353
Christian Boelsen
54+
Christian Fetzer
5455
Christian Theunert
5556
Christian Tismer
5657
Christopher Gilling

changelog/3711.feature.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Add the ``--ignore-glob`` parameter to exclude test-modules with Unix shell-style wildcards.
2+
Add the ``collect_ignore_glob`` for ``conftest.py`` to exclude test-modules with Unix shell-style wildcards.

doc/en/example/pythoncollection.rst

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ you will see that ``pytest`` only collects test-modules, which do not match the
4141
4242
========================= 5 passed in 0.02 seconds =========================
4343
44+
The ``--ignore-glob`` option allows to ignore test file paths based on Unix shell-style wildcards.
45+
If you want to exclude test-modules that end with ``_01.py``, execute ``pytest`` with ``--ignore-glob='*_01.py'``.
46+
4447
Deselect tests during test collection
4548
-------------------------------------
4649

@@ -266,3 +269,17 @@ file will be left out:
266269
collected 0 items
267270
268271
======================= no tests ran in 0.12 seconds =======================
272+
273+
It's also possible to ignore files based on Unix shell-style wildcards by adding
274+
patterns to ``collect_ignore_glob``.
275+
276+
The following example ``conftest.py`` ignores the file ``setup.py`` and in
277+
addition all files that end with ``*_py2.py`` when executed with a Python 3
278+
interpreter::
279+
280+
# content of conftest.py
281+
import sys
282+
283+
collect_ignore = ["setup.py"]
284+
if sys.version_info[0] > 2:
285+
collect_ignore_glob = ["*_py2.py"]

doc/en/reference.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,33 @@ Special Variables
797797
pytest treats some global variables in a special manner when defined in a test module.
798798

799799

800+
collect_ignore
801+
~~~~~~~~~~~~~~
802+
803+
**Tutorial**: :ref:`customizing-test-collection`
804+
805+
Can be declared in *conftest.py files* to exclude test directories or modules.
806+
Needs to be ``list[str]``.
807+
808+
.. code-block:: python
809+
810+
collect_ignore = ["setup.py"]
811+
812+
813+
collect_ignore_glob
814+
~~~~~~~~~~~~~~~~~~~
815+
816+
**Tutorial**: :ref:`customizing-test-collection`
817+
818+
Can be declared in *conftest.py files* to exclude test directories or modules
819+
with Unix shell-style wildcards. Needs to be ``list[str]`` where ``str`` can
820+
contain glob patterns.
821+
822+
.. code-block:: python
823+
824+
collect_ignore_glob = ["*_ignore.py"]
825+
826+
800827
pytest_plugins
801828
~~~~~~~~~~~~~~
802829

src/_pytest/main.py

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
from __future__ import print_function
55

66
import contextlib
7+
import fnmatch
78
import functools
89
import os
910
import pkgutil
@@ -117,6 +118,12 @@ def pytest_addoption(parser):
117118
metavar="path",
118119
help="ignore path during collection (multi-allowed).",
119120
)
121+
group.addoption(
122+
"--ignore-glob",
123+
action="append",
124+
metavar="path",
125+
help="ignore path pattern during collection (multi-allowed).",
126+
)
120127
group.addoption(
121128
"--deselect",
122129
action="append",
@@ -296,6 +303,20 @@ def pytest_ignore_collect(path, config):
296303
if py.path.local(path) in ignore_paths:
297304
return True
298305

306+
ignore_globs = config._getconftest_pathlist(
307+
"collect_ignore_glob", path=path.dirpath()
308+
)
309+
ignore_globs = ignore_globs or []
310+
excludeglobopt = config.getoption("ignore_glob")
311+
if excludeglobopt:
312+
ignore_globs.extend([py.path.local(x) for x in excludeglobopt])
313+
314+
if any(
315+
fnmatch.fnmatch(six.text_type(path), six.text_type(glob))
316+
for glob in ignore_globs
317+
):
318+
return True
319+
299320
allow_in_venv = config.getoption("collect_in_virtualenv")
300321
if not allow_in_venv and _in_venv(path):
301322
return True

testing/test_collection.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,26 @@ def pytest_configure(config):
374374
assert result.ret == 0
375375
assert "passed" in result.stdout.str()
376376

377+
def test_collectignoreglob_exclude_on_option(self, testdir):
378+
testdir.makeconftest(
379+
"""
380+
collect_ignore_glob = ['*w*l[dt]*']
381+
def pytest_addoption(parser):
382+
parser.addoption("--XX", action="store_true", default=False)
383+
def pytest_configure(config):
384+
if config.getvalue("XX"):
385+
collect_ignore_glob[:] = []
386+
"""
387+
)
388+
testdir.makepyfile(test_world="def test_hello(): pass")
389+
testdir.makepyfile(test_welt="def test_hallo(): pass")
390+
result = testdir.runpytest()
391+
assert result.ret == EXIT_NOTESTSCOLLECTED
392+
result.stdout.fnmatch_lines("*collected 0 items*")
393+
result = testdir.runpytest("--XX")
394+
assert result.ret == 0
395+
result.stdout.fnmatch_lines("*2 passed*")
396+
377397
def test_pytest_fs_collect_hooks_are_seen(self, testdir):
378398
testdir.makeconftest(
379399
"""

testing/test_session.py

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -253,6 +253,21 @@ def test_exclude(testdir):
253253
result.stdout.fnmatch_lines(["*1 passed*"])
254254

255255

256+
def test_exclude_glob(testdir):
257+
hellodir = testdir.mkdir("hello")
258+
hellodir.join("test_hello.py").write("x y syntaxerror")
259+
hello2dir = testdir.mkdir("hello2")
260+
hello2dir.join("test_hello2.py").write("x y syntaxerror")
261+
hello3dir = testdir.mkdir("hallo3")
262+
hello3dir.join("test_hello3.py").write("x y syntaxerror")
263+
subdir = testdir.mkdir("sub")
264+
subdir.join("test_hello4.py").write("x y syntaxerror")
265+
testdir.makepyfile(test_ok="def test_pass(): pass")
266+
result = testdir.runpytest("--ignore-glob=*h[ea]llo*")
267+
assert result.ret == 0
268+
result.stdout.fnmatch_lines(["*1 passed*"])
269+
270+
256271
def test_deselect(testdir):
257272
testdir.makepyfile(
258273
test_a="""

0 commit comments

Comments
 (0)