Merge pull request #2566 from jmsdvl/iss2518
Detect and warn/ignore local python installations
This commit is contained in:
commit
1485a3a902
|
@ -70,6 +70,9 @@ def pytest_addoption(parser):
|
||||||
group.addoption('--keepduplicates', '--keep-duplicates', action="store_true",
|
group.addoption('--keepduplicates', '--keep-duplicates', action="store_true",
|
||||||
dest="keepduplicates", default=False,
|
dest="keepduplicates", default=False,
|
||||||
help="Keep duplicate tests.")
|
help="Keep duplicate tests.")
|
||||||
|
group.addoption('--collect-in-virtualenv', action='store_true',
|
||||||
|
dest='collect_in_virtualenv', default=False,
|
||||||
|
help="Don't ignore tests in a local virtualenv directory")
|
||||||
|
|
||||||
group = parser.getgroup("debugconfig",
|
group = parser.getgroup("debugconfig",
|
||||||
"test session debugging and configuration")
|
"test session debugging and configuration")
|
||||||
|
@ -167,6 +170,17 @@ def pytest_runtestloop(session):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def _in_venv(path):
|
||||||
|
"""Attempts to detect if ``path`` is the root of a Virtual Environment by
|
||||||
|
checking for the existence of the appropriate activate script"""
|
||||||
|
bindir = path.join('Scripts' if sys.platform.startswith('win') else 'bin')
|
||||||
|
if not bindir.exists():
|
||||||
|
return False
|
||||||
|
activates = ('activate', 'activate.csh', 'activate.fish',
|
||||||
|
'Activate', 'Activate.bat', 'Activate.ps1')
|
||||||
|
return any([fname.basename in activates for fname in bindir.listdir()])
|
||||||
|
|
||||||
|
|
||||||
def pytest_ignore_collect(path, config):
|
def pytest_ignore_collect(path, config):
|
||||||
ignore_paths = config._getconftest_pathlist("collect_ignore", path=path.dirpath())
|
ignore_paths = config._getconftest_pathlist("collect_ignore", path=path.dirpath())
|
||||||
ignore_paths = ignore_paths or []
|
ignore_paths = ignore_paths or []
|
||||||
|
@ -177,6 +191,10 @@ def pytest_ignore_collect(path, config):
|
||||||
if py.path.local(path) in ignore_paths:
|
if py.path.local(path) in ignore_paths:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
|
allow_in_venv = config.getoption("collect_in_virtualenv")
|
||||||
|
if _in_venv(path) and not allow_in_venv:
|
||||||
|
return True
|
||||||
|
|
||||||
# Skip duplicate paths.
|
# Skip duplicate paths.
|
||||||
keepduplicates = config.getoption("keepduplicates")
|
keepduplicates = config.getoption("keepduplicates")
|
||||||
duplicate_paths = config.pluginmanager._duplicatepaths
|
duplicate_paths = config.pluginmanager._duplicatepaths
|
||||||
|
|
|
@ -0,0 +1 @@
|
||||||
|
Collection ignores local virtualenvs by default; `--collect-in-virtualenv` overrides this behavior.
|
|
@ -171,7 +171,16 @@ Builtin configuration file options
|
||||||
norecursedirs = .svn _build tmp*
|
norecursedirs = .svn _build tmp*
|
||||||
|
|
||||||
This would tell ``pytest`` to not look into typical subversion or
|
This would tell ``pytest`` to not look into typical subversion or
|
||||||
sphinx-build directories or into any ``tmp`` prefixed directory.
|
sphinx-build directories or into any ``tmp`` prefixed directory.
|
||||||
|
|
||||||
|
Additionally, ``pytest`` will attempt to intelligently identify and ignore a
|
||||||
|
virtualenv by the presence of an activation script. Any directory deemed to
|
||||||
|
be the root of a virtual environment will not be considered during test
|
||||||
|
collection unless ``‑‑collect‑in‑virtualenv`` is given. Note also that
|
||||||
|
``norecursedirs`` takes precedence over ``‑‑collect‑in‑virtualenv``; e.g. if
|
||||||
|
you intend to run tests in a virtualenv with a base directory that matches
|
||||||
|
``'.*'`` you *must* override ``norecursedirs`` in addition to using the
|
||||||
|
``‑‑collect‑in‑virtualenv`` flag.
|
||||||
|
|
||||||
.. confval:: testpaths
|
.. confval:: testpaths
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
from __future__ import absolute_import, division, print_function
|
from __future__ import absolute_import, division, print_function
|
||||||
import pytest, py
|
import pytest, py
|
||||||
|
|
||||||
from _pytest.main import Session, EXIT_NOTESTSCOLLECTED
|
from _pytest.main import Session, EXIT_NOTESTSCOLLECTED, _in_venv
|
||||||
|
|
||||||
class TestCollector(object):
|
class TestCollector(object):
|
||||||
def test_collect_versus_item(self):
|
def test_collect_versus_item(self):
|
||||||
|
@ -121,6 +121,53 @@ class TestCollectFS(object):
|
||||||
assert "test_notfound" not in s
|
assert "test_notfound" not in s
|
||||||
assert "test_found" in s
|
assert "test_found" in s
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('fname',
|
||||||
|
("activate", "activate.csh", "activate.fish",
|
||||||
|
"Activate", "Activate.bat", "Activate.ps1"))
|
||||||
|
def test_ignored_virtualenvs(self, testdir, fname):
|
||||||
|
bindir = "Scripts" if py.std.sys.platform.startswith("win") else "bin"
|
||||||
|
testdir.tmpdir.ensure("virtual", bindir, fname)
|
||||||
|
testfile = testdir.tmpdir.ensure("virtual", "test_invenv.py")
|
||||||
|
testfile.write("def test_hello(): pass")
|
||||||
|
|
||||||
|
# by default, ignore tests inside a virtualenv
|
||||||
|
result = testdir.runpytest()
|
||||||
|
assert "test_invenv" not in result.stdout.str()
|
||||||
|
# allow test collection if user insists
|
||||||
|
result = testdir.runpytest("--collect-in-virtualenv")
|
||||||
|
assert "test_invenv" in result.stdout.str()
|
||||||
|
# allow test collection if user directly passes in the directory
|
||||||
|
result = testdir.runpytest("virtual")
|
||||||
|
assert "test_invenv" in result.stdout.str()
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('fname',
|
||||||
|
("activate", "activate.csh", "activate.fish",
|
||||||
|
"Activate", "Activate.bat", "Activate.ps1"))
|
||||||
|
def test_ignored_virtualenvs_norecursedirs_precedence(self, testdir, fname):
|
||||||
|
bindir = "Scripts" if py.std.sys.platform.startswith("win") else "bin"
|
||||||
|
# norecursedirs takes priority
|
||||||
|
testdir.tmpdir.ensure(".virtual", bindir, fname)
|
||||||
|
testfile = testdir.tmpdir.ensure(".virtual", "test_invenv.py")
|
||||||
|
testfile.write("def test_hello(): pass")
|
||||||
|
result = testdir.runpytest("--collect-in-virtualenv")
|
||||||
|
assert "test_invenv" not in result.stdout.str()
|
||||||
|
# ...unless the virtualenv is explicitly given on the CLI
|
||||||
|
result = testdir.runpytest("--collect-in-virtualenv", ".virtual")
|
||||||
|
assert "test_invenv" in result.stdout.str()
|
||||||
|
|
||||||
|
@pytest.mark.parametrize('fname',
|
||||||
|
("activate", "activate.csh", "activate.fish",
|
||||||
|
"Activate", "Activate.bat", "Activate.ps1"))
|
||||||
|
def test__in_venv(self, testdir, fname):
|
||||||
|
"""Directly test the virtual env detection function"""
|
||||||
|
bindir = "Scripts" if py.std.sys.platform.startswith("win") else "bin"
|
||||||
|
# no bin/activate, not a virtualenv
|
||||||
|
base_path = testdir.tmpdir.mkdir('venv')
|
||||||
|
assert _in_venv(base_path) is False
|
||||||
|
# with bin/activate, totally a virtualenv
|
||||||
|
base_path.ensure(bindir, fname)
|
||||||
|
assert _in_venv(base_path) is True
|
||||||
|
|
||||||
def test_custom_norecursedirs(self, testdir):
|
def test_custom_norecursedirs(self, testdir):
|
||||||
testdir.makeini("""
|
testdir.makeini("""
|
||||||
[pytest]
|
[pytest]
|
||||||
|
|
Loading…
Reference in New Issue