Cloud Parts

tox

A Python tool that builds your package and runs its tests, linters or docs build in a separate virtual environment for each Python version or dependency set you list.

What it is
Automated testing (test environment managers)
Type
Open source
Made by
tox-dev
License
MIT
Facts checked
9 October 2026

What it is

You list environments in tox.toml (or under [tool.tox] in pyproject.toml). An environment named 3.12 runs on Python 3.12; one named lint can run anything. For each environment, tox creates a virtual environment, installs its dependencies, builds the project as a package and installs it the way a user would, then runs the commands and stops at the first one that fails. Environments are reused on the next run and recreated when the dependencies or Python version change. tox also strips host environment variables that aren’t passed through explicitly. The run exits with 0, and prints “congratulations :)”, only if every environment passed.

tox 4 (December 2022) was a ground-up rewrite that kept the configuration format but not the plugin API. It added subcommands such as tox run, tox parallel (tox p), tox list and tox devenv, and always builds packages in isolation through PEP 517. Native TOML configuration arrived in 4.21 (September 2024); the older INI format (tox.ini, setup.cfg) still works but is now deprecated and frozen. Environment lists can be generated from factors, so Python 3.12 to 3.14 times two Django versions is one line that expands to six environments.

By default tox creates environments with virtualenv and installs with pip. The tox-uv plugin, from the same tox-dev organisation, replaces both with uv. nox, which tox’s own docs point to, does the same job with a Python file of sessions instead of a config file, and has its own uv backend.

Why teams pick it

  • Tests the package as it is built and installed, so packaging mistakes fail the run instead of reaching users
  • One file describes every environment (Python versions, lint, docs), and the same tox command runs it on a laptop and in CI
  • Parallel mode, labels to run groups of environments, and depends to order them
  • A plugin system: tox-uv swaps in uv for faster environment creation and installs

Watch out for

  • With the default virtualenv runner it only finds Python interpreters already on the machine; installing each version is your job (tox-uv can let uv download missing ones)
  • Config is data, not code: tox’s docs suggest nox if you find the configuration too limiting
  • The INI format (tox.ini) that older projects use is deprecated and frozen, so new features need a move to TOML
  • Misplaced settings are silently ignored, and interactive programs such as debuggers need -i because tox captures output

How it fits with other technologies

Run the same tests on three Python versions, plus a lint environment · bash

cat > tox.toml <<'EOF'
env_list = ["3.12", "3.11", "3.10", "lint"]

[env_run_base]
description = "run the tests with pytest"
deps = ["pytest>=8"]
commands = [["pytest", "-q", { replace = "posargs", default = ["tests"], extend = true }]]

[env.lint]
description = "lint with ruff"
skip_install = true
deps = ["ruff"]
commands = [["ruff", "check", "."]]
EOF

tox run
#   3.12: OK (4.42=setup[4.21]+cmd[0.21] seconds)
#   3.11: OK (2.45=setup[2.25]+cmd[0.20] seconds)
#   3.10: OK (2.73=setup[2.53]+cmd[0.20] seconds)
#   lint: OK (1.95=setup[1.63]+cmd[0.32] seconds)
#   congratulations :) (11.56 seconds)

tox run -e 3.12 -- -k coupon   # one environment; args after -- replace the default `tests`
tox p                          # all environments in parallel

See it in a real stack

No architecture uses tox yet. Drop it into the playground and wire it up yourself.Open playground →
Where it came from2010–2024

Holger Krekel released tox 0.5 on PyPI in July 2010 as “virtualenv-based automation of test activities”: check that a package installs correctly with different Python versions and interpreters, run the tests in each environment with the test tool of your choice, and act as a frontend to CI servers so CI and local testing share one setup.

tox reached 1.0 in May 2011, 2.0 in 2015 and 3.0 in 2018, and now lives in the tox-dev organisation on GitHub. Its maintainers, Bernát Gábor among them, then rebuilt it from the ground up: alphas were out by January 2021 and tox 4.0 shipped in December 2022, keeping the configuration format but redesigning the command line around subcommands and requiring plugins to be rewritten.

In September 2024 tox 4.21 added native TOML configuration, and the original INI format was later deprecated and frozen. The tox-uv plugin lets the same configuration run on uv instead of virtualenv and pip.

Why it’s built this way

One virtualenv per environment
The point was to check that a package installs and passes its tests on each Python version and interpreter, which needs a clean, separate environment for each.
Build and install the package before testing
tox’s first stated job is checking that a package builds and installs correctly in each environment, which only works if the tests run against the installed package. tox 4 always builds in isolation, as PEP 517 and PEP 518 specify.
A frontend for CI, not a CI system
Running the same commands locally and on the CI server reduces boilerplate and merges CI and shell-based testing into one definition.
TOML over INI
TOML has proper types and avoids INI ambiguities such as multi-line values and comment escaping, so new features go only to TOML.

Timeline

  1. 2010

    Holger Krekel releases tox 0.5 (July)

  2. 2011

    tox 1.0 (May)

  3. 2018

    tox 3.0 (April)

  4. 2021

    First alpha of the rewritten tox 4 (January)

  5. 2022

    tox 4.0 released (December)

  6. 2024

    tox 4.21 adds native TOML configuration (September)

Sources10 · facts checked 9 October 2026

Improve this page on GitHub