Saltar a contenido

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