From fc5d4654e5f6ec11eac5f5fcd5e4ba840414925a Mon Sep 17 00:00:00 2001 From: Christian Fetzer Date: Tue, 5 Feb 2019 17:19:24 +0100 Subject: [PATCH 1/3] Add ability to exclude files matching glob patterns with --ignore-glob This adds the `--ignore-glob` option to allow Unix-style wildcards so that `--ignore-glob=integration*` excludes all tests that reside in files starting with `integration`. Fixes: #3711 --- AUTHORS | 1 + changelog/3711.feature.rst | 1 + doc/en/example/pythoncollection.rst | 3 +++ src/_pytest/main.py | 18 ++++++++++++++++++ testing/test_session.py | 15 +++++++++++++++ 5 files changed, 38 insertions(+) create mode 100644 changelog/3711.feature.rst diff --git a/AUTHORS b/AUTHORS index 35e07dcb4..737c07b1b 100644 --- a/AUTHORS +++ b/AUTHORS @@ -50,6 +50,7 @@ Charles Cloud Charnjit SiNGH (CCSJ) Chris Lamb Christian Boelsen +Christian Fetzer Christian Theunert Christian Tismer Christopher Gilling diff --git a/changelog/3711.feature.rst b/changelog/3711.feature.rst new file mode 100644 index 000000000..ba3322dfb --- /dev/null +++ b/changelog/3711.feature.rst @@ -0,0 +1 @@ +Add the ``--ignore-glob`` parameter to exclude test-modules with Unix shell-style wildcards. diff --git a/doc/en/example/pythoncollection.rst b/doc/en/example/pythoncollection.rst index 8dcaa97d7..15eb63187 100644 --- a/doc/en/example/pythoncollection.rst +++ b/doc/en/example/pythoncollection.rst @@ -41,6 +41,9 @@ you will see that ``pytest`` only collects test-modules, which do not match the ========================= 5 passed in 0.02 seconds ========================= +The ``--ignore-glob`` option allows to ignore test file paths based on Unix shell-style wildcards. +If you want to exclude test-modules that end with ``_01.py``, execute ``pytest`` with ``--ignore-glob='*_01.py'``. + Deselect tests during test collection ------------------------------------- diff --git a/src/_pytest/main.py b/src/_pytest/main.py index d0d826bb6..1d0c48c27 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -4,6 +4,7 @@ from __future__ import division from __future__ import print_function import contextlib +import fnmatch import functools import os import pkgutil @@ -117,6 +118,12 @@ def pytest_addoption(parser): metavar="path", help="ignore path during collection (multi-allowed).", ) + group.addoption( + "--ignore-glob", + action="append", + metavar="path", + help="ignore path pattern during collection (multi-allowed).", + ) group.addoption( "--deselect", action="append", @@ -296,6 +303,17 @@ def pytest_ignore_collect(path, config): if py.path.local(path) in ignore_paths: return True + ignore_globs = [] + excludeglobopt = config.getoption("ignore_glob") + if excludeglobopt: + ignore_globs.extend([py.path.local(x) for x in excludeglobopt]) + + if any( + fnmatch.fnmatch(six.text_type(path), six.text_type(glob)) + for glob in ignore_globs + ): + return True + allow_in_venv = config.getoption("collect_in_virtualenv") if not allow_in_venv and _in_venv(path): return True diff --git a/testing/test_session.py b/testing/test_session.py index d64a1a519..6b185f76b 100644 --- a/testing/test_session.py +++ b/testing/test_session.py @@ -253,6 +253,21 @@ def test_exclude(testdir): result.stdout.fnmatch_lines(["*1 passed*"]) +def test_exclude_glob(testdir): + hellodir = testdir.mkdir("hello") + hellodir.join("test_hello.py").write("x y syntaxerror") + hello2dir = testdir.mkdir("hello2") + hello2dir.join("test_hello2.py").write("x y syntaxerror") + hello3dir = testdir.mkdir("hallo3") + hello3dir.join("test_hello3.py").write("x y syntaxerror") + subdir = testdir.mkdir("sub") + subdir.join("test_hello4.py").write("x y syntaxerror") + testdir.makepyfile(test_ok="def test_pass(): pass") + result = testdir.runpytest("--ignore-glob=*h[ea]llo*") + assert result.ret == 0 + result.stdout.fnmatch_lines(["*1 passed*"]) + + def test_deselect(testdir): testdir.makepyfile( test_a=""" From 2dc2a19db5bd88afbbf8aa5a2d6703bfaf279766 Mon Sep 17 00:00:00 2001 From: Christian Fetzer Date: Wed, 6 Feb 2019 10:50:46 +0100 Subject: [PATCH 2/3] Add ability to exclude files matching glob patterns in conftest.py This adds the `collect_ignore_glob` option for `conftest.py` to allow Unix-style wildcards for excluding files. --- changelog/3711.feature.rst | 1 + doc/en/example/pythoncollection.rst | 14 ++++++++++++++ src/_pytest/main.py | 5 ++++- testing/test_collection.py | 20 ++++++++++++++++++++ 4 files changed, 39 insertions(+), 1 deletion(-) diff --git a/changelog/3711.feature.rst b/changelog/3711.feature.rst index ba3322dfb..1503bac60 100644 --- a/changelog/3711.feature.rst +++ b/changelog/3711.feature.rst @@ -1 +1,2 @@ Add the ``--ignore-glob`` parameter to exclude test-modules with Unix shell-style wildcards. +Add the ``collect_ignore_glob`` for ``conftest.py`` to exclude test-modules with Unix shell-style wildcards. diff --git a/doc/en/example/pythoncollection.rst b/doc/en/example/pythoncollection.rst index 15eb63187..750bc58d8 100644 --- a/doc/en/example/pythoncollection.rst +++ b/doc/en/example/pythoncollection.rst @@ -269,3 +269,17 @@ file will be left out: collected 0 items ======================= no tests ran in 0.12 seconds ======================= + +It's also possible to ignore files based on Unix shell-style wildcards by adding +patterns to ``collect_ignore_glob``. + +The following example ``conftest.py`` ignores the file ``setup.py`` and in +addition all files that end with ``*_py2.py`` when executed with a Python 3 +interpreter:: + + # content of conftest.py + import sys + + collect_ignore = ["setup.py"] + if sys.version_info[0] > 2: + collect_ignore_glob = ["*_py2.py"] diff --git a/src/_pytest/main.py b/src/_pytest/main.py index 1d0c48c27..9d4a9f962 100644 --- a/src/_pytest/main.py +++ b/src/_pytest/main.py @@ -303,7 +303,10 @@ def pytest_ignore_collect(path, config): if py.path.local(path) in ignore_paths: return True - ignore_globs = [] + ignore_globs = config._getconftest_pathlist( + "collect_ignore_glob", path=path.dirpath() + ) + ignore_globs = ignore_globs or [] excludeglobopt = config.getoption("ignore_glob") if excludeglobopt: ignore_globs.extend([py.path.local(x) for x in excludeglobopt]) diff --git a/testing/test_collection.py b/testing/test_collection.py index 36e8a69ce..8ed5caa3a 100644 --- a/testing/test_collection.py +++ b/testing/test_collection.py @@ -374,6 +374,26 @@ class TestCustomConftests(object): assert result.ret == 0 assert "passed" in result.stdout.str() + def test_collectignoreglob_exclude_on_option(self, testdir): + testdir.makeconftest( + """ + collect_ignore_glob = ['*w*l[dt]*'] + def pytest_addoption(parser): + parser.addoption("--XX", action="store_true", default=False) + def pytest_configure(config): + if config.getvalue("XX"): + collect_ignore_glob[:] = [] + """ + ) + testdir.makepyfile(test_world="def test_hello(): pass") + testdir.makepyfile(test_welt="def test_hallo(): pass") + result = testdir.runpytest() + assert result.ret == EXIT_NOTESTSCOLLECTED + result.stdout.fnmatch_lines("*collected 0 items*") + result = testdir.runpytest("--XX") + assert result.ret == 0 + result.stdout.fnmatch_lines("*2 passed*") + def test_pytest_fs_collect_hooks_are_seen(self, testdir): testdir.makeconftest( """ From 1876a928d3dfc038cf25550385acb19cef69a188 Mon Sep 17 00:00:00 2001 From: Christian Fetzer Date: Wed, 6 Feb 2019 17:15:28 +0100 Subject: [PATCH 3/3] Document collect_ignore and collect_ignore_glob in reference --- doc/en/reference.rst | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/doc/en/reference.rst b/doc/en/reference.rst index 92e298a88..c1e22f854 100644 --- a/doc/en/reference.rst +++ b/doc/en/reference.rst @@ -797,6 +797,33 @@ Special Variables pytest treats some global variables in a special manner when defined in a test module. +collect_ignore +~~~~~~~~~~~~~~ + +**Tutorial**: :ref:`customizing-test-collection` + +Can be declared in *conftest.py files* to exclude test directories or modules. +Needs to be ``list[str]``. + +.. code-block:: python + + collect_ignore = ["setup.py"] + + +collect_ignore_glob +~~~~~~~~~~~~~~~~~~~ + +**Tutorial**: :ref:`customizing-test-collection` + +Can be declared in *conftest.py files* to exclude test directories or modules +with Unix shell-style wildcards. Needs to be ``list[str]`` where ``str`` can +contain glob patterns. + +.. code-block:: python + + collect_ignore_glob = ["*_ignore.py"] + + pytest_plugins ~~~~~~~~~~~~~~