Resolve symlinks for args

This fixes running `pytest tests/test_foo.py::test_bar`, where `tests`
is a symlink to `project/app/tests`: previously
`project/app/conftest.py` would be ignored for fixtures then.
This commit is contained in:
Daniel Hahler 2018-10-10 16:56:18 +02:00
parent 24c83d725a
commit 7268462b33
5 changed files with 71 additions and 10 deletions

View File

@ -0,0 +1,5 @@
Resolve symbolic links for args.
This fixes running ``pytest tests/test_foo.py::test_bar``, where ``tests``
is a symlink to ``project/app/tests``:
previously ``project/app/conftest.py`` would be ignored for fixtures then.

View File

@ -1175,7 +1175,7 @@ class FixtureManager(object):
def pytest_plugin_registered(self, plugin): def pytest_plugin_registered(self, plugin):
nodeid = None nodeid = None
try: try:
p = py.path.local(plugin.__file__) p = py.path.local(plugin.__file__).realpath()
except AttributeError: except AttributeError:
pass pass
else: else:

View File

@ -490,7 +490,7 @@ class Session(nodes.FSCollector):
from _pytest.python import Package from _pytest.python import Package
names = self._parsearg(arg) names = self._parsearg(arg)
argpath = names.pop(0) argpath = names.pop(0).realpath()
paths = [] paths = []
root = self root = self

View File

@ -753,16 +753,26 @@ class TestInvocationVariants(object):
monkeypatch.syspath_prepend(p) monkeypatch.syspath_prepend(p)
# module picked up in symlink-ed directory: # module picked up in symlink-ed directory:
# It picks up local/lib/foo/bar (symlink) via sys.path.
result = testdir.runpytest("--pyargs", "-v", "foo.bar") result = testdir.runpytest("--pyargs", "-v", "foo.bar")
testdir.chdir() testdir.chdir()
assert result.ret == 0 assert result.ret == 0
result.stdout.fnmatch_lines( if hasattr(py.path.local, "mksymlinkto"):
[ result.stdout.fnmatch_lines(
"*lib/foo/bar/test_bar.py::test_bar*PASSED*", [
"*lib/foo/bar/test_bar.py::test_other*PASSED*", "lib/foo/bar/test_bar.py::test_bar <- local/lib/foo/bar/test_bar.py PASSED*",
"*2 passed*", "lib/foo/bar/test_bar.py::test_other <- local/lib/foo/bar/test_bar.py PASSED*",
] "*2 passed*",
) ]
)
else:
result.stdout.fnmatch_lines(
[
"local/lib/foo/bar/test_bar.py::test_bar PASSED*",
"local/lib/foo/bar/test_bar.py::test_other PASSED*",
"*2 passed*",
]
)
def test_cmdline_python_package_not_exists(self, testdir): def test_cmdline_python_package_not_exists(self, testdir):
result = testdir.runpytest("--pyargs", "tpkgwhatv") result = testdir.runpytest("--pyargs", "tpkgwhatv")

View File

@ -4,7 +4,7 @@ import textwrap
import py import py
import pytest import pytest
from _pytest.config import PytestPluginManager from _pytest.config import PytestPluginManager
from _pytest.main import EXIT_NOTESTSCOLLECTED, EXIT_USAGEERROR from _pytest.main import EXIT_NOTESTSCOLLECTED, EXIT_OK, EXIT_USAGEERROR
@pytest.fixture(scope="module", params=["global", "inpackage"]) @pytest.fixture(scope="module", params=["global", "inpackage"])
@ -186,6 +186,52 @@ def test_conftest_confcutdir(testdir):
assert "warning: could not load initial" not in result.stdout.str() assert "warning: could not load initial" not in result.stdout.str()
@pytest.mark.skipif(
not hasattr(py.path.local, "mksymlinkto"),
reason="symlink not available on this platform",
)
def test_conftest_symlink(testdir):
"""Ensure that conftest.py is used for resolved symlinks."""
realtests = testdir.tmpdir.mkdir("real").mkdir("app").mkdir("tests")
testdir.tmpdir.join("symlinktests").mksymlinkto(realtests)
testdir.makepyfile(
**{
"real/app/tests/test_foo.py": "def test1(fixture): pass",
"real/conftest.py": textwrap.dedent(
"""
import pytest
print("conftest_loaded")
@pytest.fixture
def fixture():
print("fixture_used")
"""
),
}
)
result = testdir.runpytest("-vs", "symlinktests")
result.stdout.fnmatch_lines(
[
"*conftest_loaded*",
"real/app/tests/test_foo.py::test1 fixture_used",
"PASSED",
]
)
assert result.ret == EXIT_OK
realtests.ensure("__init__.py")
result = testdir.runpytest("-vs", "symlinktests/test_foo.py::test1")
result.stdout.fnmatch_lines(
[
"*conftest_loaded*",
"real/app/tests/test_foo.py::test1 fixture_used",
"PASSED",
]
)
assert result.ret == EXIT_OK
def test_no_conftest(testdir): def test_no_conftest(testdir):
testdir.makeconftest("assert 0") testdir.makeconftest("assert 0")
result = testdir.runpytest("--noconftest") result = testdir.runpytest("--noconftest")