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