Merge pull request #10988 from nicoddemus/initial-testpaths-10987
Consider testpaths for initial conftests
This commit is contained in:
commit
76d15231f5
|
@ -0,0 +1 @@
|
||||||
|
Fix bug where very long option names could cause pytest to break with ``OSError: [Errno 36] File name too long`` on some systems.
|
|
@ -0,0 +1 @@
|
||||||
|
:confval:`testpaths` is now honored to load root ``conftests``.
|
|
@ -1713,13 +1713,12 @@ passed multiple times. The expected format is ``name=value``. For example::
|
||||||
|
|
||||||
.. confval:: testpaths
|
.. confval:: testpaths
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Sets list of directories that should be searched for tests when
|
Sets list of directories that should be searched for tests when
|
||||||
no specific directories, files or test ids are given in the command line when
|
no specific directories, files or test ids are given in the command line when
|
||||||
executing pytest from the :ref:`rootdir <rootdir>` directory.
|
executing pytest from the :ref:`rootdir <rootdir>` directory.
|
||||||
File system paths may use shell-style wildcards, including the recursive
|
File system paths may use shell-style wildcards, including the recursive
|
||||||
``**`` pattern.
|
``**`` pattern.
|
||||||
|
|
||||||
Useful when all project tests are in a known location to speed up
|
Useful when all project tests are in a known location to speed up
|
||||||
test collection and to avoid picking up undesired tests by accident.
|
test collection and to avoid picking up undesired tests by accident.
|
||||||
|
|
||||||
|
@ -1728,8 +1727,17 @@ passed multiple times. The expected format is ``name=value``. For example::
|
||||||
[pytest]
|
[pytest]
|
||||||
testpaths = testing doc
|
testpaths = testing doc
|
||||||
|
|
||||||
This tells pytest to only look for tests in ``testing`` and ``doc``
|
This configuration means that executing:
|
||||||
directories when executing from the root directory.
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
pytest
|
||||||
|
|
||||||
|
has the same practical effects as executing:
|
||||||
|
|
||||||
|
.. code-block:: console
|
||||||
|
|
||||||
|
pytest testing doc
|
||||||
|
|
||||||
|
|
||||||
.. confval:: tmp_path_retention_count
|
.. confval:: tmp_path_retention_count
|
||||||
|
@ -1744,7 +1752,7 @@ passed multiple times. The expected format is ``name=value``. For example::
|
||||||
[pytest]
|
[pytest]
|
||||||
tmp_path_retention_count = 3
|
tmp_path_retention_count = 3
|
||||||
|
|
||||||
Default: 3
|
Default: ``3``
|
||||||
|
|
||||||
|
|
||||||
.. confval:: tmp_path_retention_policy
|
.. confval:: tmp_path_retention_policy
|
||||||
|
@ -1763,7 +1771,7 @@ passed multiple times. The expected format is ``name=value``. For example::
|
||||||
[pytest]
|
[pytest]
|
||||||
tmp_path_retention_policy = "all"
|
tmp_path_retention_policy = "all"
|
||||||
|
|
||||||
Default: all
|
Default: ``all``
|
||||||
|
|
||||||
|
|
||||||
.. confval:: usefixtures
|
.. confval:: usefixtures
|
||||||
|
|
|
@ -526,7 +526,10 @@ class PytestPluginManager(PluginManager):
|
||||||
# Internal API for local conftest plugin handling.
|
# Internal API for local conftest plugin handling.
|
||||||
#
|
#
|
||||||
def _set_initial_conftests(
|
def _set_initial_conftests(
|
||||||
self, namespace: argparse.Namespace, rootpath: Path
|
self,
|
||||||
|
namespace: argparse.Namespace,
|
||||||
|
rootpath: Path,
|
||||||
|
testpaths_ini: Sequence[str],
|
||||||
) -> None:
|
) -> None:
|
||||||
"""Load initial conftest files given a preparsed "namespace".
|
"""Load initial conftest files given a preparsed "namespace".
|
||||||
|
|
||||||
|
@ -543,7 +546,7 @@ class PytestPluginManager(PluginManager):
|
||||||
)
|
)
|
||||||
self._noconftest = namespace.noconftest
|
self._noconftest = namespace.noconftest
|
||||||
self._using_pyargs = namespace.pyargs
|
self._using_pyargs = namespace.pyargs
|
||||||
testpaths = namespace.file_or_dir
|
testpaths = namespace.file_or_dir + testpaths_ini
|
||||||
foundanchor = False
|
foundanchor = False
|
||||||
for testpath in testpaths:
|
for testpath in testpaths:
|
||||||
path = str(testpath)
|
path = str(testpath)
|
||||||
|
@ -552,7 +555,14 @@ class PytestPluginManager(PluginManager):
|
||||||
if i != -1:
|
if i != -1:
|
||||||
path = path[:i]
|
path = path[:i]
|
||||||
anchor = absolutepath(current / path)
|
anchor = absolutepath(current / path)
|
||||||
if anchor.exists(): # we found some file object
|
|
||||||
|
# Ensure we do not break if what appears to be an anchor
|
||||||
|
# is in fact a very long option (#10169).
|
||||||
|
try:
|
||||||
|
anchor_exists = anchor.exists()
|
||||||
|
except OSError: # pragma: no cover
|
||||||
|
anchor_exists = False
|
||||||
|
if anchor_exists:
|
||||||
self._try_load_conftest(anchor, namespace.importmode, rootpath)
|
self._try_load_conftest(anchor, namespace.importmode, rootpath)
|
||||||
foundanchor = True
|
foundanchor = True
|
||||||
if not foundanchor:
|
if not foundanchor:
|
||||||
|
@ -1131,7 +1141,9 @@ class Config:
|
||||||
@hookimpl(trylast=True)
|
@hookimpl(trylast=True)
|
||||||
def pytest_load_initial_conftests(self, early_config: "Config") -> None:
|
def pytest_load_initial_conftests(self, early_config: "Config") -> None:
|
||||||
self.pluginmanager._set_initial_conftests(
|
self.pluginmanager._set_initial_conftests(
|
||||||
early_config.known_args_namespace, rootpath=early_config.rootpath
|
early_config.known_args_namespace,
|
||||||
|
rootpath=early_config.rootpath,
|
||||||
|
testpaths_ini=self.getini("testpaths"),
|
||||||
)
|
)
|
||||||
|
|
||||||
def _initini(self, args: Sequence[str]) -> None:
|
def _initini(self, args: Sequence[str]) -> None:
|
||||||
|
|
|
@ -1247,6 +1247,48 @@ def test_collect_pyargs_with_testpaths(
|
||||||
result.stdout.fnmatch_lines(["*1 passed in*"])
|
result.stdout.fnmatch_lines(["*1 passed in*"])
|
||||||
|
|
||||||
|
|
||||||
|
def test_initial_conftests_with_testpaths(pytester: Pytester) -> None:
|
||||||
|
"""The testpaths ini option should load conftests in those paths as 'initial' (#10987)."""
|
||||||
|
p = pytester.mkdir("some_path")
|
||||||
|
p.joinpath("conftest.py").write_text(
|
||||||
|
textwrap.dedent(
|
||||||
|
"""
|
||||||
|
def pytest_sessionstart(session):
|
||||||
|
raise Exception("pytest_sessionstart hook successfully run")
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
pytester.makeini(
|
||||||
|
"""
|
||||||
|
[pytest]
|
||||||
|
testpaths = some_path
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
result = pytester.runpytest()
|
||||||
|
result.stdout.fnmatch_lines(
|
||||||
|
"INTERNALERROR* Exception: pytest_sessionstart hook successfully run"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_large_option_breaks_initial_conftests(pytester: Pytester) -> None:
|
||||||
|
"""Long option values do not break initial conftests handling (#10169)."""
|
||||||
|
option_value = "x" * 1024 * 1000
|
||||||
|
pytester.makeconftest(
|
||||||
|
"""
|
||||||
|
def pytest_addoption(parser):
|
||||||
|
parser.addoption("--xx", default=None)
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
pytester.makepyfile(
|
||||||
|
f"""
|
||||||
|
def test_foo(request):
|
||||||
|
assert request.config.getoption("xx") == {option_value!r}
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
result = pytester.runpytest(f"--xx={option_value}")
|
||||||
|
assert result.ret == 0
|
||||||
|
|
||||||
|
|
||||||
def test_collect_symlink_file_arg(pytester: Pytester) -> None:
|
def test_collect_symlink_file_arg(pytester: Pytester) -> None:
|
||||||
"""Collect a direct symlink works even if it does not match python_files (#4325)."""
|
"""Collect a direct symlink works even if it does not match python_files (#4325)."""
|
||||||
real = pytester.makepyfile(
|
real = pytester.makepyfile(
|
||||||
|
|
|
@ -35,7 +35,7 @@ def conftest_setinitial(
|
||||||
self.importmode = "prepend"
|
self.importmode = "prepend"
|
||||||
|
|
||||||
namespace = cast(argparse.Namespace, Namespace())
|
namespace = cast(argparse.Namespace, Namespace())
|
||||||
conftest._set_initial_conftests(namespace, rootpath=Path(args[0]))
|
conftest._set_initial_conftests(namespace, rootpath=Path(args[0]), testpaths_ini=[])
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.usefixtures("_sys_snapshot")
|
@pytest.mark.usefixtures("_sys_snapshot")
|
||||||
|
|
Loading…
Reference in New Issue