Fix pytest with mixed up filename casing.

This commit is contained in:
Christian Neumüller 2019-08-26 17:18:46 +02:00
parent 0215bcd84e
commit 505c3340bf
2 changed files with 37 additions and 11 deletions

View File

@ -36,6 +36,10 @@ hookimpl = HookimplMarker("pytest")
hookspec = HookspecMarker("pytest")
def _uniquepath(path):
return type(path)(os.path.normcase(str(path.realpath())))
class ConftestImportFailure(Exception):
def __init__(self, path, excinfo):
Exception.__init__(self, path, excinfo)
@ -366,7 +370,7 @@ class PytestPluginManager(PluginManager):
"""
current = py.path.local()
self._confcutdir = (
current.join(namespace.confcutdir, abs=True)
_uniquepath(current.join(namespace.confcutdir, abs=True))
if namespace.confcutdir
else None
)
@ -405,19 +409,18 @@ class PytestPluginManager(PluginManager):
else:
directory = path
directory = _uniquepath(directory)
# XXX these days we may rather want to use config.rootdir
# and allow users to opt into looking into the rootdir parent
# directories instead of requiring to specify confcutdir
clist = []
for parent in directory.realpath().parts():
for parent in directory.parts():
if self._confcutdir and self._confcutdir.relto(parent):
continue
conftestpath = parent.join("conftest.py")
if conftestpath.isfile():
# Use realpath to avoid loading the same conftest twice
# with build systems that create build directories containing
# symlinks to actual files.
mod = self._importconftest(conftestpath.realpath())
mod = self._importconftest(conftestpath)
clist.append(mod)
self._dirpath2confmods[directory] = clist
return clist
@ -432,6 +435,10 @@ class PytestPluginManager(PluginManager):
raise KeyError(name)
def _importconftest(self, conftestpath):
# Use realpath to avoid loading the same conftest twice
# with build systems that create build directories containing
# symlinks to actual files.
conftestpath = _uniquepath(conftestpath)
try:
return self._conftestpath2mod[conftestpath]
except KeyError:

View File

@ -3,8 +3,9 @@ import textwrap
import py
import pytest
from _pytest.config import PytestPluginManager
from _pytest.config import PytestPluginManager, _uniquepath
from _pytest.main import ExitCode
import os.path
def ConftestWithSetinitial(path):
@ -141,11 +142,11 @@ def test_conftestcutdir(testdir):
# but we can still import a conftest directly
conftest._importconftest(conf)
values = conftest._getconftestmodules(conf.dirpath())
assert values[0].__file__.startswith(str(conf))
assert values[0].__file__.startswith(str(_uniquepath(conf)))
# and all sub paths get updated properly
values = conftest._getconftestmodules(p)
assert len(values) == 1
assert values[0].__file__.startswith(str(conf))
assert values[0].__file__.startswith(str(_uniquepath(conf)))
def test_conftestcutdir_inplace_considered(testdir):
@ -154,7 +155,7 @@ def test_conftestcutdir_inplace_considered(testdir):
conftest_setinitial(conftest, [conf.dirpath()], confcutdir=conf.dirpath())
values = conftest._getconftestmodules(conf.dirpath())
assert len(values) == 1
assert values[0].__file__.startswith(str(conf))
assert values[0].__file__.startswith(str(_uniquepath(conf)))
@pytest.mark.parametrize("name", "test tests whatever .dotdir".split())
@ -164,7 +165,7 @@ def test_setinitial_conftest_subdirs(testdir, name):
conftest = PytestPluginManager()
conftest_setinitial(conftest, [sub.dirpath()], confcutdir=testdir.tmpdir)
if name not in ("whatever", ".dotdir"):
assert subconftest in conftest._conftestpath2mod
assert _uniquepath(subconftest) in conftest._conftestpath2mod
assert len(conftest._conftestpath2mod) == 1
else:
assert subconftest not in conftest._conftestpath2mod
@ -274,6 +275,24 @@ def test_conftest_symlink_files(testdir):
result.stdout.fnmatch_lines(["*conftest_loaded*", "PASSED"])
assert result.ret == ExitCode.OK
@pytest.mark.skipif(
os.path.normcase('x') != os.path.normcase('X'),
reason="only relevant for case insensitive file systems",
)
def test_conftest_badcase(testdir):
"""Check conftest.py loading when directory casing is wrong."""
testdir.tmpdir.mkdir("JenkinsRoot").mkdir("test")
source = {
"setup.py": "",
"test/__init__.py": "",
"test/conftest.py": ""
}
testdir.makepyfile(**{"JenkinsRoot/%s" % k: v for k, v in source.items()})
testdir.tmpdir.join("jenkinsroot/test").chdir()
result = testdir.runpytest()
assert result.ret == ExitCode.NO_TESTS_COLLECTED
def test_no_conftest(testdir):
testdir.makeconftest("assert 0")