1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328
|
.. _getting_started:
#################
Getting Started
#################
This tutorial walks you through creating your first tox project from scratch. By the end, you will have a working tox
configuration that runs tests and linting across multiple Python versions.
***************
Prerequisites
***************
Before starting, make sure you have:
- Python 3.10 or later installed
- tox installed (see :doc:`../how-to/install`)
- A Python project you want to test (or follow along to create one)
Verify tox is available:
.. code-block:: bash
tox --version
***********************************
Creating your first configuration
***********************************
tox needs a configuration file where you define what tools to run and how to set up environments for them. tox supports
two configuration formats: TOML and INI. **TOML is the recommended format for new projects** -- it is more robust, has
proper type support, and avoids ambiguities inherent in INI parsing. INI remains supported for existing projects.
Create a ``tox.toml`` (or ``tox.ini``) at the root of your project:
.. tab:: TOML
.. code-block:: toml
env_list = ["3.13", "3.12", "lint"]
[env_run_base]
description = "run the test suite with pytest"
deps = [
"pytest>=8",
]
commands = [["pytest", { replace = "posargs", default = ["tests"], extend = true }]]
[env.lint]
description = "run linters"
skip_install = true
deps = ["ruff"]
commands = [["ruff", "check", { replace = "posargs", default = ["."], extend = true }]]
.. tab:: INI
.. code-block:: ini
[tox]
env_list = 3.13, 3.12, lint
[testenv]
description = run the test suite with pytest
deps =
pytest>=8
commands =
pytest {posargs:tests}
[testenv:lint]
description = run linters
skip_install = true
deps =
ruff
commands = ruff check {posargs:.}
.. tip::
You can also generate a ``tox.ini`` file automatically by running ``tox quickstart`` and answering a few questions.
*********************************
Understanding the configuration
*********************************
The configuration has two parts: **core settings** and **environment settings**.
Core settings
=============
Core settings affect all environments or configure how tox itself behaves. They live at the root level in ``tox.toml``
(or under the ``[tox]`` section in ``tox.ini``).
.. tab:: TOML
.. code-block:: toml
env_list = ["3.13", "3.12", "lint"]
.. tab:: INI
.. code-block:: ini
[tox]
env_list = 3.13, 3.12, lint
The :ref:`env_list` setting defines which environments run by default when you invoke ``tox`` without specifying any.
Both formats support generating environment matrices from factor combinations — INI uses curly-brace expansion
(``3.{10-}``), while TOML uses ``product`` dicts (``{ product = [{ prefix = "py3", start = 10 }, ["django42"]] }``). See
:ref:`generative-environment-list` for details. For the full list of core options, see :ref:`conf-core`.
Environment settings
====================
Each tox environment has its own configuration. Settings defined at the base level (``env_run_base`` in TOML,
``testenv`` in INI) are inherited by all environments unless overridden. Individual environments are configured under
``env.<name>`` in TOML or ``testenv:<name>`` in INI.
.. tab:: TOML
.. code-block:: toml
[env_run_base]
description = "run the test suite with pytest"
deps = ["pytest>=8"]
commands = [["pytest", { replace = "posargs", default = ["tests"], extend = true }]]
[env.lint]
description = "run linters"
skip_install = true
deps = ["ruff"]
commands = [["ruff", "check", "."]]
.. tab:: INI
.. code-block:: ini
[testenv]
description = run the test suite with pytest
deps =
pytest>=8
commands =
pytest {posargs:tests}
[testenv:lint]
description = run linters
skip_install = true
deps =
ruff
commands = ruff check .
Here the ``lint`` environment overrides the base settings entirely, while ``3.13`` and ``3.12`` inherit from the base.
.. tip::
Options must go in the correct section — placing a core option in an environment section (or vice versa) silently
has no effect. Run ``tox run -v`` or ``tox config`` to check for misplaced keys.
Environment names and Python versions
=====================================
Environment names can consist of alphanumeric characters, dashes, and dots. Names are split on dashes into **factors**
-- for example ``py311-django42`` splits into factors ``py311`` and ``django42``. Additionally, the current platform
(like ``linux``, ``darwin``, ``win32``) is automatically available as an implicit factor for conditional configuration.
tox recognizes certain naming patterns and automatically sets the Python interpreter:
- ``N.M``: CPython N.M (e.g. ``3.13``) -- **preferred**
- ``pyNM`` or ``pyN.M``: CPython N.M (e.g. ``py313`` or ``py3.13``) -- legacy, still supported
- ``pypyNM``: PyPy N.M
- ``cpythonNM``: CPython N.M
- ``graalpyNM``: GraalPy N.M
Prefer the ``N.M`` form (e.g. ``3.14``) over ``pyNMM`` (e.g. ``py314``). The dotted form is unambiguous, reads more
naturally in environment lists and CI output, and avoids confusion for Python versions >= 3.10 where the concatenated
digits become three characters.
If the name doesn't match any pattern, tox uses the same Python as the one tox is installed into (this is the case for
``lint`` in our example). To override this fallback, set :ref:`default_base_python`:
.. code-block:: toml
[env_run_base]
default_base_python = ["3.14", "3.13"]
This pins a default Python version for environments without a Python factor, improving reproducibility across machines
with different system Pythons.
.. tip::
If your project uses :PEP:`751` lock files (``pylock.toml``), you can install locked dependencies via :ref:`pylock`
instead of listing packages in ``deps``.
For the full list of environment options, see :ref:`conf-testenv`.
Scaling to multiple Python versions
===================================
When your test matrix grows beyond a few environments, use ``env_base`` sections to define named templates that generate
environments from factor combinations:
.. code-block:: toml
[env_base.test]
factors = [["3.13", "3.14"]]
deps = ["pytest>=8"]
commands = [["pytest"]]
This generates ``test-3.13`` and ``test-3.14``, each inheriting deps and commands from the template. The template itself
inherits from ``env_run_base``, so global defaults still apply. See :ref:`env-base-templates` for details.
***************************
Running your environments
***************************
Run all default environments (those listed in :ref:`env_list`):
.. code-block:: bash
tox
Run a specific environment:
.. code-block:: bash
tox run -e lint
Run multiple environments:
.. code-block:: bash
tox run -e 3.13,lint
Pass extra arguments to the underlying tool using ``--``:
.. code-block:: bash
# Run pytest in verbose mode
tox run -e 3.13 -- -v
# Run ruff on a specific file
tox run -e lint -- src/mymodule.py
The ``{ replace = "posargs" }`` in TOML (or ``{posargs}`` in INI) is a placeholder that gets replaced by whatever you
pass after ``--``.
**************************
Understanding the output
**************************
On the first run, tox creates virtual environments and installs dependencies. Subsequent runs reuse existing
environments unless dependencies change:
.. code-block:: bash
$ tox run -e 3.13,lint
3.13: install_deps> python -m pip install 'pytest>=8'
3.13: commands[0]> pytest tests
========================= 3 passed in 0.12s =========================
3.13: OK ✔ in 5.43s
lint: install_deps> python -m pip install ruff
lint: commands[0]> ruff check .
All checks passed!
lint: OK ✔ in 2.11s
3.13: OK (5.43=setup[3.21]+cmd[2.22] seconds)
lint: OK (2.11=setup[1.05]+cmd[1.06] seconds)
congratulations :)
tox will automatically detect changes to your dependencies and recreate environments when needed. You can force a full
recreation with the ``-r`` flag:
.. code-block:: bash
tox run -e 3.13 -r
If tools inside the environment maintain their own caches (e.g. pre-commit), you can use :ref:`recreate_commands` to
clean them before the environment directory is removed. See :ref:`howto_clean_caches` for details.
If you want to rerun tests without reinstalling dependencies or the package (e.g. when working offline or when nothing
has changed), use ``--skip-env-install``:
.. code-block:: bash
tox run -e 3.13 --skip-env-install
********************************
Listing available environments
********************************
See all configured environments and their descriptions:
.. code-block:: bash
$ tox list
default environments:
3.13 -> run the test suite with pytest
3.12 -> run the test suite with pytest
lint -> run linters
**************************
Inspecting configuration
**************************
View the resolved configuration for an environment:
.. code-block:: bash
tox config -e 3.13 -k deps commands
The output format can be changed with ``--format`` and written to a file with ``-o``:
.. code-block:: bash
tox config -e 3.13 --format json -o config.json
tox config -e 3.13 --format toml -o config.toml
This is useful for debugging configuration issues and for programmatic consumption.
************
Next steps
************
Now that you have a working tox setup, explore these topics:
- :doc:`../explanation` -- understand how tox works (parallel mode, packaging, auto-provisioning)
- :doc:`../how-to/usage` -- practical recipes for common tasks (including testing across old and new Python versions
with :ref:`virtualenv_spec`)
- :ref:`configuration` -- full configuration reference
- :ref:`cli` -- complete CLI reference
|