Skip to content

Commit

Permalink
Resolve symlinks for args
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
blueyed committed Oct 12, 2018
1 parent 4c9015c commit 8bb1427
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 5 deletions.
1 change: 1 addition & 0 deletions changelog/4108.bugfix.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Resolve symbolic links for args.
2 changes: 1 addition & 1 deletion src/_pytest/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -1172,7 +1172,7 @@ def getfixtureinfo(self, node, func, cls, funcargs=True):
def pytest_plugin_registered(self, plugin):
nodeid = None
try:
p = py.path.local(plugin.__file__)
p = py.path.local(plugin.__file__).realpath()
except AttributeError:
pass
else:
Expand Down
2 changes: 1 addition & 1 deletion src/_pytest/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -487,7 +487,7 @@ def _collect(self, arg):
from _pytest.python import Package

names = self._parsearg(arg)
argpath = names.pop(0)
argpath = names.pop(0).realpath()
paths = []

root = self
Expand Down
5 changes: 3 additions & 2 deletions testing/acceptance_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -733,13 +733,14 @@ def join_pythonpath(*dirs):
monkeypatch.syspath_prepend(p)

# 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")
testdir.chdir()
assert result.ret == 0
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*",
"lib/foo/bar/test_bar.py::test_other <- local/lib/foo/bar/test_bar.py PASSED*",
"*2 passed*",
]
)
Expand Down
44 changes: 43 additions & 1 deletion testing/test_conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import py
import pytest
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"])
Expand Down Expand Up @@ -186,6 +186,48 @@ def pytest_addoption(parser):
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):
testdir.makeconftest("assert 0")
result = testdir.runpytest("--noconftest")
Expand Down

0 comments on commit 8bb1427

Please sign in to comment.