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:
parent
24c83d725a
commit
7268462b33
|
@ -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.
|
|
@ -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:
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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")
|
||||||
|
|
|
@ -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")
|
||||||
|
|
Loading…
Reference in New Issue