This document covers AfterPython's testing infrastructure and multi-Python version support system. It explains the testing framework configuration, how to run tests across multiple Python versions locally using pixi environments, and how the CI/CD pipeline automatically validates code against all supported Python versions.
For information about the complete CI/CD pipeline including linting and deployment, see CI/CD and Deployment. For details on pixi package management features, see pixi Package Manager.
AfterPython uses pytest as its testing framework with support for parallel test execution via pytest-xdist. The test infrastructure is designed to work seamlessly with both traditional Python package managers (uv) and cross-platform environment managers (pixi).
AfterPython officially supports Python 3.11, 3.12, and 3.13. Python 3.14 support is planned but not yet enabled in the default test tasks.
Python Version Declaration:
| File | Configuration | Supported Versions |
|---|---|---|
pixi.toml | python | >=3.11.14 |
pixi.toml | environments | py311, py312, py313, py314 |
Sources: pixi.toml20 pixi.toml48-53
The test dependencies are managed through pixi's feature system, allowing them to be optionally included in specific environments.
Sources: pixi.toml62-68
AfterPython uses pixi's environment and feature system to create isolated Python version environments for testing.
Sources: pixi.toml19-53 pixi.toml71-81
| Environment | Python Version | Features | Purpose |
|---|---|---|---|
default | 3.11.* | py311, dev, optional | Default development environment |
py311 | 3.11.* | py311, test, optional | Python 3.11 testing |
py312 | 3.12.* | py312, test, optional | Python 3.12 testing |
py313 | 3.13.* | py313, test, optional | Python 3.13 testing |
py314 | 3.14.* | py314, test, optional | Python 3.14 testing (experimental) |
Sources: pixi.toml48-53
Test Single Python Version:
Test All Python Versions:
The test-all task is configured to run tests across specific Python environments sequentially:
Sources: pixi.toml11-17 pixi.toml67-68
The test task is defined in the [feature.test.tasks] section:
Command Flags:
-v: Verbose output showing individual test results.-n auto: Parallel test execution using all available CPU cores (via pytest-xdist).Sources: pixi.toml67-68
For projects or contributors not using pixi, tests can be run with standard Python tools using the generated CI template logic:
Sources: .github/workflows/ci.yml92-98 src/afterpython/templates/ci-workflow-template.yml92-98
AfterPython implements an adaptive CI testing strategy that automatically detects whether to use pixi or uv-based testing workflows based on the presence of a pixi.toml file.
Detection Job Implementation:
The detect-test-strategy job checks for the presence of pixi.toml in the repository root:
Sources: .github/workflows/ci.yml45-60 src/afterpython/templates/ci-workflow-template.yml45-60
The test-uv job runs when pixi.toml is not detected, using traditional Python matrix testing:
UV Test Job Configuration:
| Step | Action | Details |
|---|---|---|
| Checkout | actions/checkout@v6 | Clone repository |
| Setup Python | actions/setup-python@v6 | Install matrix Python version |
| Install uv | astral-sh/setup-uv@v7 | Install uv package manager |
| Install deps | uv pip install --system . --group test | Install package and test dependencies |
| Run tests | pytest -v | Execute tests with verbose output |
Exit Code Handling:
Exit code 5 (no tests collected) is treated as success, allowing projects without tests to pass CI.
Sources: .github/workflows/ci.yml64-98 src/afterpython/templates/ci-workflow-template.yml64-98
The test-pixi job runs when pixi.toml is detected, using pixi's environment system:
Pixi Test Job Configuration:
| Step | Action | Details |
|---|---|---|
| Checkout | actions/checkout@v6 | Clone repository |
| Setup pixi | prefix-dev/setup-pixi@v0.9.5 | Install pixi v0.67.2 with caching |
| Run tests | pixi run -e {env} test | Execute test task in specific environment |
Matrix Strategy:
Sources: .github/workflows/ci.yml102-135 src/afterpython/templates/ci-workflow-template.yml102-135
The test job consolidates results from both test strategies to provide a single status check for branch protection:
Sources: .github/workflows/ci.yml139-156 src/afterpython/templates/ci-workflow-template.yml139-156
The CI pipeline includes a build verification job that ensures the package can be built and installed correctly.
| Step | Action |
|---|---|
| Build package | uv build |
| Install built package | uv pip install --system dist/*.whl |
| Verify installation | python -c "import {package_name}" |
The verification step dynamically extracts the project name from pyproject.toml and converts it to a valid import name (replacing - with _).
Sources: .github/workflows/ci.yml160-202 src/afterpython/templates/ci-workflow-template.yml160-202
If a project has no tests yet, the CI pipeline still succeeds:
The test task uses pytest -n auto to run tests in parallel:
pytest-xdist plugin.Each pixi environment is isolated:
Pixi CI configuration enables caching for faster builds:
This caches downloaded packages and environment states across workflow runs.
Sources: .github/workflows/ci.yml120 pixi.toml68
AfterPython's testing infrastructure provides:
pytest-xdist with auto-detection of CPU cores.ap init get this full testing infrastructure automatically via template workflows.Refresh this wiki