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.
 | 
				
			||||||
| 
						 | 
					@ -173,6 +173,15 @@ Builtin configuration file options
 | 
				
			||||||
   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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
   .. versionadded:: 2.8
 | 
					   .. versionadded:: 2.8
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -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