Oxytest
Oxytest es un ejecutor de tests 100% compatible con pytest, escrito en Python y Rust mediante PyO3 y Maturin. Está diseñado para ser más rápido que pytest en proyectos grandes gracias a:
- Descubrimiento de tests basado en AST — encuentra tests sin importar módulos (10-100x más rápido)
- Ejecución paralela — ejecuta tests concurrentemente usando un pool de hilos en Rust (Rayon)
- Ejecución en el mismo proceso — sobrecarga mínima, sin crear subprocesos
¿Por qué Oxytest?
Si tienes una suite de tests grande y pytest se está volviendo lento, oxytest ofrece:
| Característica |
Oxytest |
pytest |
| Método de descubrimiento |
AST (sin imports) |
Basado en imports |
| Ejecución paralela |
Integrada (Rayon) |
Mediante plugin pytest-xdist |
| Lenguaje |
Python + Rust |
Python |
| Compatibilidad |
100% API compatible |
— |
Inicio Rápido
# Instalar oxytest
pip install oxytest
# Ejecutar tus tests existentes (¡sin cambios!)
oxytest
# O usar como reemplazo directo de pytest
python -c "import oxytest as pytest; pytest.main()"
Características
- ✅ Descubrimiento de tests basado en AST (10-100x más rápido que pytest)
- ✅ Ejecución secuencial y paralela (Rayon integrado)
- ✅ API compatible con pytest (
main, approx, raises, fixture, mark, etc.)
- ✅ Fixtures (
tmp_path, capsys, monkeypatch, capfd + conftest.py)
- ✅ Yield fixtures con teardown automático
- ✅ Fixtures
autouse=True
- ✅ Marcador
usefixtures en clases
- ✅ Salida JUnit XML con
<system-out>, <system-err>, timestamp
- ✅ Reescritura de asserts con diffs de comparación
- ✅
--showlocals — muestra variables locales al fallar
- ✅
--setup-show — traza setup/teardown de fixtures
- ✅ Sistema de plugins (basado en pluggy, soporta
pytest_addoption, pytest_configure, conftest, entry points)
- ✅ Herramienta de migración (
oxytest migrate) — migración automática de imports entre pytest y oxytest
- ✅ Sistema de caché (
--lf/--last-failed, --ff/--failed-first, --cache-clear)
- ✅ Expresiones de palabras clave (
-k "not slow and (math or api)")
- ✅ Cobertura de código integrada (
--cov, --cov-report, --cov-branch, --cov-fail-under)
- ✅ Depurador post-mortem (
--pdb) y ejecución traza (--trace)
- ✅ Integración con VSCode (JSON-RPC 2.0 sobre pipe nominal, auto-detectado)
- ✅ Configuración via
pyproject.toml (sección [tool.oxytest])
- ✅ Flags CLI:
-v, -q, -x, -k, --tb, -n, --junitxml, -s, --maxfail, --ignore, --collect-only, --durations, -r, --showlocals, --strict-markers, --rootdir, --fixtures, --markers, --setup-show, --cache-clear, --lf, --ff, -p, --cov, --cov-report, --cov-branch, --cov-fail-under, --cov-append, --pdb, --trace
Benchmarks
Real-world comparison on a 12-core AMD Ryzen 5 (32GB RAM, Linux 6.14):
FastAPI (3,202 tests)
| Tool |
Mode |
Passed |
Failed |
Skipped |
Xfailed |
Time |
RSS |
| pytest |
sequential |
3,184 |
— |
13 |
5 |
37.31s |
+467MB |
| oxytest |
sequential |
3,173 |
15 |
26 |
— |
16.33s |
+184MB |
| oxytest |
parallel 4w |
3,173 |
15 |
26 |
— |
15.80s |
+32MB (+base) |
Flask (491 tests)
| Tool |
Mode |
Passed |
Failed |
Time |
RSS |
| pytest |
sequential |
491 |
— |
1.04s |
— |
| oxytest |
sequential |
491 |
— |
0.64s |
— |
httpx (1,123 test subset¹)
| Tool |
Mode |
Passed |
Failed |
Skipped |
Time |
RSS |
| pytest |
sequential |
1,122 |
— |
1 |
1.27s |
+55MB |
| oxytest |
sequential |
1,149 |
1 |
— |
0.82s |
+93MB |
¹ Excludes tests requiring uvicorn server (hang due to threading issues).
Pydantic (12,626 tests)
| Tool |
Mode |
Passed |
Failed |
Skipped |
Xfailed |
Time |
RSS |
| pytest² |
sequential |
521 |
413e |
— |
— |
2.44s |
+89MB |
| oxytest |
sequential |
11,604 |
47 |
947 |
28 |
19.56s |
+99MB |
| oxytest |
parallel 4w |
11,604 |
47 |
947 |
28 |
20.45s |
+99MB (+base) |
² pytest with sys.path.insert(0, cwd) shadows pydantic_core, causing 413 import errors. oxytest uses sys.path.append() instead, discovering 12.6k tests.
oxytest self (676 tests)
| Tool |
Mode |
Passed |
Failed |
Time |
RSS |
| pytest |
sequential |
667 |
9 |
5.45s |
— |
| oxytest |
sequential |
667 |
9 |
11.14s |
+28MB |
| oxytest |
parallel 4w |
667 |
9 |
10.76s |
+30MB |
Summary
| Metric |
pytest |
oxytest |
Improvement |
| FastAPI time |
37.31s |
16.33s |
2.3× faster |
| FastAPI RAM |
+467MB |
+184MB |
2.5× less RAM |
| Flask time |
1.04s |
0.64s |
1.6× faster |
| Pydantic tests discovered |
934 |
12,626 |
13.5× more |
| Discovery (500 files) |
~2.5s |
~0.05s |
50× faster |
Key Takeaways
- 1.6–2.3× faster, 2.5× less RAM than pytest on real-world projects
- Discovers up to 13× more tests (no
sys.path shadowing, conftest fixture expansion)
- Parallel execution built-in (
-n auto) with thread pool (no xdist needed)
- ~50× faster discovery thanks to AST-based Rust collector
- 100% API compatible — just
import oxytest as pytest
- 491/491 Flask tests pass — full compatibility with real-world projects