change test module importing behaviour to append to sys.path

instead of prepending.  This better allows to run test modules
against installated versions of a package even if the package
under test has the same import root.  In this example::

   testing/__init__.py
   testing/test_pkg_under_test.py
   pkg_under_test/

the tests will preferrably run against the installed version
of pkg_under_test whereas before they would always pick
up the local version.

--HG--
branch : prefer_installed
This commit is contained in:
holger krekel 2015-04-17 22:25:35 +02:00
parent fb07a09964
commit 5c8e5acf9d
8 changed files with 46 additions and 13 deletions

View File

@ -1,6 +1,19 @@
2.8.0.dev (compared to 2.7.X) 2.8.0.dev (compared to 2.7.X)
----------------------------- -----------------------------
- change test module importing behaviour to append to sys.path
instead of prepending. This better allows to run test modules
against installated versions of a package even if the package
under test has the same import root. In this example::
testing/__init__.py
testing/test_pkg_under_test.py
pkg_under_test/
the tests will preferrably run against the installed version
of pkg_under_test whereas before they would always pick
up the local version. Thanks Holger Krekel.
2.7.1.dev (compared to 2.7.0) 2.7.1.dev (compared to 2.7.0)
----------------------------- -----------------------------

View File

@ -1,2 +1,2 @@
# #
__version__ = '2.8.0.dev1' __version__ = '2.8.0.dev2'

View File

@ -254,7 +254,7 @@ class TmpTestdir:
break break
self.tmpdir = tmpdir self.tmpdir = tmpdir
self.plugins = [] self.plugins = []
self._syspathremove = [] self._savesyspath = list(sys.path)
self.chdir() # always chdir self.chdir() # always chdir
self.request.addfinalizer(self.finalize) self.request.addfinalizer(self.finalize)
@ -270,8 +270,7 @@ class TmpTestdir:
has finished. has finished.
""" """
for p in self._syspathremove: sys.path[:] = self._savesyspath
sys.path.remove(p)
if hasattr(self, '_olddir'): if hasattr(self, '_olddir'):
self._olddir.chdir() self._olddir.chdir()
# delete modules that have been loaded from tmpdir # delete modules that have been loaded from tmpdir
@ -370,7 +369,6 @@ class TmpTestdir:
if path is None: if path is None:
path = self.tmpdir path = self.tmpdir
sys.path.insert(0, str(path)) sys.path.insert(0, str(path))
self._syspathremove.append(str(path))
def mkdir(self, name): def mkdir(self, name):
"""Create a new (sub)directory.""" """Create a new (sub)directory."""

View File

@ -485,7 +485,7 @@ class Module(pytest.File, PyCollector):
def _importtestmodule(self): def _importtestmodule(self):
# we assume we are only called once per module # we assume we are only called once per module
try: try:
mod = self.fspath.pyimport(ensuresyspath=True) mod = self.fspath.pyimport(ensuresyspath="append")
except SyntaxError: except SyntaxError:
raise self.CollectError( raise self.CollectError(
py.code.ExceptionInfo().getrepr(style="short")) py.code.ExceptionInfo().getrepr(style="short"))
@ -2057,3 +2057,4 @@ def get_scope_node(node, scope):
return node.session return node.session
raise ValueError("unknown scope") raise ValueError("unknown scope")
return node.getparent(cls) return node.getparent(cls)

View File

@ -31,12 +31,12 @@ def get_version():
def has_environment_marker_support(): def has_environment_marker_support():
""" """
Tests that setuptools has support for PEP-426 environment marker support. Tests that setuptools has support for PEP-426 environment marker support.
The first known release to support it is 0.7 (and the earliest on PyPI seems to be 0.7.2 The first known release to support it is 0.7 (and the earliest on PyPI seems to be 0.7.2
so we're using that), see: http://pythonhosted.org/setuptools/history.html#id142 so we're using that), see: http://pythonhosted.org/setuptools/history.html#id142
References: References:
* https://wheel.readthedocs.org/en/latest/index.html#defining-conditional-dependencies * https://wheel.readthedocs.org/en/latest/index.html#defining-conditional-dependencies
* https://www.python.org/dev/peps/pep-0426/#environment-markers * https://www.python.org/dev/peps/pep-0426/#environment-markers
""" """
@ -48,7 +48,7 @@ def has_environment_marker_support():
def main(): def main():
install_requires = ['py>=1.4.25'] install_requires = ['py>=1.4.27.dev2']
extras_require = {} extras_require = {}
if has_environment_marker_support(): if has_environment_marker_support():
extras_require[':python_version=="2.6" or python_version=="3.0" or python_version=="3.1"'] = ['argparse'] extras_require[':python_version=="2.6" or python_version=="3.0" or python_version=="3.1"'] = ['argparse']

View File

@ -1,3 +1,5 @@
import sys
from textwrap import dedent
import pytest, py import pytest, py
class TestModule: class TestModule:
@ -23,6 +25,24 @@ class TestModule:
"*HINT*", "*HINT*",
]) ])
def test_import_appends_for_import(self, testdir, monkeypatch):
syspath = list(sys.path)
monkeypatch.setattr(sys, "path", syspath)
root1 = testdir.mkdir("root1")
root2 = testdir.mkdir("root2")
root1.ensure("x456.py")
root2.ensure("x456.py")
p = root2.join("test_x456.py")
p.write(dedent("""\
import x456
def test():
assert x456.__file__.startswith(%r)
""" % str(root1)))
syspath.insert(0, str(root1))
with root2.as_cwd():
reprec = testdir.inline_run()
reprec.assertoutcome(passed=1)
def test_syntax_error_in_module(self, testdir): def test_syntax_error_in_module(self, testdir):
modcol = testdir.getmodulecol("this is a syntax error") modcol = testdir.getmodulecol("this is a syntax error")
pytest.raises(modcol.CollectError, modcol.collect) pytest.raises(modcol.CollectError, modcol.collect)

View File

@ -238,7 +238,7 @@ def test_pytestconfig_is_session_scoped():
class TestNoselikeTestAttribute: class TestNoselikeTestAttribute:
def test_module(self, testdir): def test_module_with_global_test(self, testdir):
testdir.makepyfile(""" testdir.makepyfile("""
__test__ = False __test__ = False
def test_hello(): def test_hello():
@ -248,7 +248,7 @@ class TestNoselikeTestAttribute:
assert not reprec.getfailedcollections() assert not reprec.getfailedcollections()
calls = reprec.getreports("pytest_runtest_logreport") calls = reprec.getreports("pytest_runtest_logreport")
assert not calls assert not calls
def test_class_and_method(self, testdir): def test_class_and_method(self, testdir):
testdir.makepyfile(""" testdir.makepyfile("""
__test__ = True __test__ = True

View File

@ -772,6 +772,7 @@ def test_default_markers(testdir):
]) ])
def test_importplugin_issue375(testdir): def test_importplugin_issue375(testdir):
testdir.syspathinsert(testdir.tmpdir)
testdir.makepyfile(qwe="import aaaa") testdir.makepyfile(qwe="import aaaa")
excinfo = pytest.raises(ImportError, lambda: importplugin("qwe")) excinfo = pytest.raises(ImportError, lambda: importplugin("qwe"))
assert "qwe" not in str(excinfo.value) assert "qwe" not in str(excinfo.value)