Skip to content

Commit 6eb5c4f

Browse files
authored
✨ feat(packaging): declare tox.pytest deps via a testing extra (#3940)
The `tox.pytest` module exposes a pytest plugin for testing tox itself and tox plugins, but its runtime imports of `pytest`, `pytest-mock` and `devpi-process` were never declared in the package metadata. 🐛 Plugin authors who wired `pytest_plugins = "tox.pytest"` into their `conftest.py` had to discover and pin those transitive dependencies by hand, and would otherwise hit an `ImportError` on `devpi_process` before any test could run, as reported in #3938. The fix exposes them through a new `testing` optional dependency, so consumers can pull the full fixture surface in via `tox[testing]` while the base install stays free of test-only packages. ✨ The version floors mirror those already in the `test` dependency group used by tox itself, keeping a single source of truth for the supported lower bounds. Plugin-author docs in `docs/plugin/howto.rst` gain a short `Testing plugins` section pointing at the new extra and showing the `pytest_plugins` hookup, so the workflow is discoverable from the plugin guide. Closes #3938.
1 parent 1ad47dd commit 6eb5c4f

7 files changed

Lines changed: 47 additions & 0 deletions

File tree

‎docs/changelog/3938.feature.rst‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Declare the runtime dependencies of the ``tox.pytest`` plugin (``pytest``, ``devpi-process`` and ``pytest-mock``) under
2+
a new ``testing`` extra, so plugin authors can pull them in via ``tox[testing]`` - by :user:`gaborbernat`.

‎docs/changelog/3940.feature.rst‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Declare the runtime dependencies of the ``tox.pytest`` plugin (``pytest``, ``devpi-process`` and ``pytest-mock``) under
2+
a new ``testing`` extra, so plugin authors can pull them in via ``tox[testing]`` - by :user:`gaborbernat`.

‎docs/plugin/api.rst‎

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,3 +153,18 @@ session
153153

154154
.. autoclass:: tox.tox_env.info.Info
155155
:members:
156+
157+
testing
158+
=======
159+
160+
.. automodule:: tox.pytest
161+
:no-members:
162+
163+
.. autoclass:: tox.pytest.ToxProject
164+
:members:
165+
166+
.. autoclass:: tox.pytest.ToxProjectCreator
167+
:members:
168+
169+
.. autoclass:: tox.pytest.ToxRunOutcome
170+
:members:

‎docs/plugin/howto.rst‎

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,27 @@ In ``src/tox_myplugin/__init__.py``, define your hooks exactly as in ``toxfile.p
200200
201201
After ``pip install tox-myplugin``, tox discovers the plugin automatically via the entry point.
202202

203+
*****************
204+
Testing plugins
205+
*****************
206+
207+
tox ships a pytest plugin at :mod:`tox.pytest` with fixtures for spinning up isolated tox projects, faking package
208+
indexes, and capturing output. To use it, declare a dependency on the ``testing`` extra so that ``pytest``,
209+
``pytest-mock`` and ``devpi-process`` are pulled in:
210+
211+
.. code-block:: toml
212+
213+
[dependency-groups]
214+
test = [
215+
"tox[testing]",
216+
]
217+
218+
Then register the plugin in your ``conftest.py``:
219+
220+
.. code-block:: python
221+
222+
pytest_plugins = "tox.pytest"
223+
203224
*********
204225
Logging
205226
*********

‎pyproject.toml‎

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,11 @@ dependencies = [
6565
optional-dependencies.completion = [
6666
"argcomplete>=3.6.3",
6767
]
68+
optional-dependencies.testing = [
69+
"devpi-process>=1.1.1",
70+
"pytest>=9.0.2",
71+
"pytest-mock>=3.15.1",
72+
]
6873
urls."Release Notes" = "https://tox.wiki/en/latest/changelog.html"
6974
urls.Documentation = "https://tox.wiki"
7075
urls.Homepage = "http://tox.readthedocs.org"

‎tests/session/cmd/test_sequential.py‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -535,6 +535,7 @@ def test_machine_factor_run_env(tox_project: ToxProjectCreator) -> None:
535535
assert py_journal["machine"] == py_info.machine
536536

537537

538+
@pytest.mark.timeout(120)
538539
def test_machine_factor_unavailable(tox_project: ToxProjectCreator) -> None:
539540
ini = "[testenv]\npackage=skip\nbase_python=cpython3-64-fakearch999"
540541
proj = tox_project({"tox.ini": ini})

‎tox.toml‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ uv_seed = true
7070
description = "build documentation"
7171
base_python = [ "3.14" ]
7272
dependency_groups = [ "docs" ]
73+
extras = [ "testing" ]
7374
commands = [
7475
[
7576
"sphinx-build",

0 commit comments

Comments
 (0)