tox Cheat Sheet
Overview
tox is a command-line tool for automating Python testing across multiple environments. It creates isolated virtual environments, installs dependencies, and runs test commands for each configured environment. tox is commonly used to verify that packages work across different Python versions and dependency combinations before publishing.
tox 4.x uses tox.ini or pyproject.toml for configuration and supports parallel execution, conditional environments, dependency pinning, and integration with CI/CD systems. It replaces manual virtual environment management with declarative configuration.
Installation
pip install tox
# or
pipx install tox
# Verify
tox --version
Core Commands
| Command | Description |
|---|---|
tox | Run all default environments |
tox -e py312 | Run specific environment |
tox -e py310,py311,py312 | Run multiple environments |
tox -p | Run environments in parallel |
tox -l | List configured environments |
tox --listenvs-all | List all environments |
tox -r | Recreate environments |
tox -e lint | Run lint environment |
tox --devenv venv | Create dev environment |
tox config | Show resolved configuration |
Configuration
tox.ini
[tox]
env_list = py310, py311, py312, lint, typecheck
min_version = 4.0
[testenv]
deps =
pytest>=7.0
pytest-cov
-r requirements.txt
commands =
pytest {posargs:tests/}
[testenv:lint]
deps = ruff
commands = ruff check src/ tests/
[testenv:typecheck]
deps =
mypy
types-requests
commands = mypy src/
[testenv:docs]
deps =
mkdocs
mkdocs-material
commands = mkdocs build
pyproject.toml
[tool.tox]
env_list = ["py310", "py311", "py312", "lint"]
min_version = "4.0"
[tool.tox.env_run_base]
deps = ["pytest>=7.0", "pytest-cov"]
commands = [["pytest", "{posargs:tests/}"]]
[tool.tox.env.lint]
deps = ["ruff"]
commands = [["ruff", "check", "src/", "tests/"]]
Environment Variables and Settings
[testenv]
deps = pytest
set_env =
PYTHONPATH = {toxinidir}/src
DATABASE_URL = sqlite:///test.db
CI = true
pass_env =
HOME
SSH_AUTH_SOCK
AWS_*
commands = pytest {posargs}
Advanced Usage
Dependency Matrix
[tox]
env_list = py{310,311,312}-django{42,50}
[testenv]
deps =
pytest
django42: Django>=4.2,<4.3
django50: Django>=5.0,<5.1
commands = pytest {posargs}
Parallel Execution
# Run all environments in parallel
tox -p auto
# Run with limited parallelism
tox -p 4
# Show live output
tox -p auto -o
Conditional Configuration
[testenv]
deps =
pytest
py310: importlib-metadata
platform =
linux: linux
macos: darwin
commands =
python -m pytest {posargs}
Pre/Post Commands
[testenv]
deps = pytest
commands_pre =
python -c "print('Setting up...')"
commands =
pytest {posargs}
commands_post =
python -c "print('Cleaning up...')"
Factor-Based Config
[testenv:coverage-{py310,py311,py312}]
deps =
pytest
pytest-cov
commands =
pytest --cov=src --cov-report=xml {posargs}
Troubleshooting
| Issue | Solution |
|---|---|
| Python version not found | Install the Python version; check python3.x is in PATH |
| Dependency install fails | Use -r to recreate env; check constraints |
| Tests pass locally but fail in tox | Check set_env and pass_env settings |
| Slow environment creation | Use --skip-missing-interpreters in CI |
| Package install fails | Verify pyproject.toml build config |
# Recreate all environments
tox -r
# Show environment config
tox config -e py312
# Pass arguments to pytest
tox -- -x -v tests/test_specific.py
# Skip missing interpreters
tox --skip-missing-interpreters
# Verbose output
tox -v