How to Test Against Multiple Python Versions Using uv
A library that works on Python 3.11 can break on 3.12 because of removed deprecations, C API changes, or subtle differences in standard library behavior. Catching these failures before your users do requires running tests against each version you support. uv makes this straightforward: it downloads Python versions on demand, so there is no need to install them yourself.
Prerequisites
- uv installed on your system
- A Python project with pytest configured as a dependency (see Setting up testing with pytest and uv)
Run Tests Against a Single Alternate Version
Pass --python to select a specific Python version:
uv run --python 3.12 pytestIf Python 3.12 is not already installed, uv downloads and installs it automatically. This works with any CPython version uv supports.
Run Tests Against Multiple Versions
Loop over the versions you need:
for version in 3.10 3.11 3.12 3.13 3.14; do
echo "=== Python $version ==="
uv run --python $version pytest
doneIf you use a justfile, add a recipe:
test-all-pythons:
#!/usr/bin/env bash
for version in 3.10 3.11 3.12 3.13 3.14; do
echo "=== Python $version ==="
uv run --python $version pytest || exit 1
doneRun it with:
just test-all-pythonsTest Against an Upcoming Pre-Release
To catch breakage in the next Python before it ships, add the upcoming version to the loop. Python 3.15 reached beta 1 on 7 May 2026 (final release scheduled for October 2026), and uv installs pre-releases with the same command:
for version in 3.13 3.14 3.15; do
echo "=== Python $version ==="
uv run --python $version pytest
doneuv run --python 3.15 resolves to whatever 3.15 pre-release python-build-standalone has most recently published. To pin a specific pre-release for reproducibility, use the full version (uv run --python 3.15.0b1 pytest). Expect failures during pre-release testing: dependencies often lack wheels for new Python versions and either fall back to source builds or refuse to install.
Constrain Which Versions to Test
The requires-python field in pyproject.toml declares which Python versions your project supports:
[project]
requires-python = ">=3.10"uv respects this constraint when resolving dependencies. If you ask uv to run against a version outside this range, it will refuse with an error explaining the conflict. Keep requires-python in sync with the versions you test against.
Alternatives for Complex Test Matrices
A shell loop works well for running the same tests across a few Python versions. For more complex scenarios (testing with different dependency combinations, running in parallel, or generating reports), dedicated test automation tools are a better fit:
- tox with the tox-uv plugin integrates tox’s matrix support with uv’s fast dependency resolution
- nox gives you a Python-scripted session runner that pairs well with uv through nox’s uv backend
See Also
- Setting up GitHub Actions with uv for running multi-version tests in CI
- How to run tests using uv for basic test execution
- uv documentation on Python versions