Cuando una suite crece, ejecutarla completa puede tardar cada vez más. Una forma de reducir el tiempo total es ejecutar pruebas en paralelo.
En este tema usaremos pytest-xdist para paralelizar la suite y veremos qué condiciones debe cumplir una prueba para ejecutarse correctamente junto a otras.
pytest-xdist es una extensión de pytest que permite distribuir pruebas en varios procesos. Cada proceso ejecuta una parte de la suite.
Esto puede reducir el tiempo total de ejecución, especialmente cuando hay muchas pruebas independientes.
Si ya seguiste el tema de instalación de herramientas, pytest-xdist debería estar instalado. Para instalarlo o confirmarlo:
python -m pip install pytest-xdist
Luego ejecuta:
python -m pytest --version
La salida debe mostrar que pytest está disponible. Si pytest-xdist está instalado, podrás usar la opción -n.
Para ejecutar la suite usando procesos automáticos:
python -m pytest -n auto
-n auto permite que pytest-xdist elija la cantidad de procesos según el equipo.
También puedes indicar una cantidad específica:
python -m pytest -n 2
Este comando ejecuta pruebas usando dos procesos. A veces conviene usar un número fijo para que el comportamiento sea más predecible.
La ejecución paralela suele ayudar cuando:
Puede ser mejor no paralelizar si:
Una prueba que usa tmp_path suele ser apta para paralelo porque cada prueba recibe su propia carpeta temporal:
from app.archivos import escribir_texto
def test_escribir_texto_crea_archivo_con_contenido(tmp_path):
ruta = tmp_path / "salida.txt"
escribir_texto(ruta, "Contenido")
assert ruta.read_text(encoding="utf-8") == "Contenido"
No comparte archivos con otras pruebas.
Esta prueba puede causar problemas si varias pruebas escriben el mismo archivo:
from pathlib import Path
def test_escribe_archivo_compartido():
ruta = Path("salida.txt")
ruta.write_text("dato", encoding="utf-8")
assert ruta.exists()
Si otras pruebas usan salida.txt, pueden interferir entre sí. Es mejor usar tmp_path.
El estado global puede causar fallas difíciles de diagnosticar. Por ejemplo:
contador = 0
def incrementar():
global contador
contador += 1
return contador
Si varias pruebas dependen del valor de contador, el resultado puede variar según el proceso y el orden. Es mejor evitar estado global o reiniciarlo explícitamente con fixtures.
Una señal de mala independencia es que una prueba pase sola, pero falle cuando se ejecuta con toda la suite o en paralelo.
Ejecuta una prueba específica y luego toda la suite:
python -m pytest tests/test_archivos.py
python -m pytest -n auto
Si el resultado cambia, revisa estado compartido, archivos compartidos o dependencias externas.
La salida con -n muestra que se crearon workers. Por ejemplo:
created: 2/2 workers
Eso indica que pytest-xdist está distribuyendo pruebas en procesos separados.
Puedes combinar paralelo con selección por marcador:
python -m pytest -n auto -m "not lento"
También con una carpeta:
python -m pytest tests -n auto
Agrega un argumento para ejecución paralela:
parser.add_argument("--paralelo", action="store_true", help="Ejecuta pruebas en paralelo con pytest-xdist")
Luego, en construir_comando:
if args.paralelo:
comando.extend(["-n", "auto"])
Así puedes ejecutar:
python run_tests.py --paralelo
Una alternativa más flexible es aceptar un número:
parser.add_argument("--workers", help="Cantidad de procesos para pytest-xdist")
Y en construir_comando:
if args.workers:
comando.extend(["-n", args.workers])
Uso:
python run_tests.py --workers auto
python run_tests.py --workers 2
Si una prueba no puede ejecutarse en paralelo por una razón concreta, declárala con un marcador:
markers =
no_paralelo: pruebas que no deben ejecutarse en paralelo por usar recursos compartidos
Luego marca la prueba:
import pytest
@pytest.mark.no_paralelo
def test_recurso_compartido():
assert True
Para ejecutar en paralelo excluyendo esas pruebas:
python -m pytest -n auto -m "not no_paralelo"
Luego puedes ejecutar las no paralelizables aparte:
python -m pytest -m no_paralelo
Lo ideal es reducir al mínimo este grupo.
También puedes generar reportes HTML con ejecución paralela:
python -m pytest -n auto --html=reports/reporte.html --self-contained-html
Si el reporte falla o queda incompleto, prueba primero sin paralelizar para aislar si el problema está en las pruebas o en la configuración del reporte.
tmp_path para archivos temporales.monkeypatch.pytest-xdist.-n 2.-n para aislar el problema.Actualiza run_tests.py para aceptar --workers. Debe permitir estos comandos:
python run_tests.py --workers auto
python run_tests.py --workers 2
python run_tests.py --workers auto --tipo rapida
Luego ejecuta la suite en paralelo y revisa si aparece alguna falla que no estaba en la ejecución secuencial.
En leer_argumentos:
parser.add_argument("--workers", help="Cantidad de procesos para pytest-xdist")
En construir_comando:
if args.workers:
comando.extend(["-n", args.workers])
Ejecuta:
python run_tests.py --workers auto
Antes de continuar con el próximo tema, verifica lo siguiente:
pytest-xdist está instalado.python -m pytest -n auto.tmp_path para archivos temporales.--workers si lo implementaste.En este tema ejecutamos pruebas en paralelo con pytest-xdist. La paralelización puede reducir tiempos, pero exige pruebas bien aisladas y sin estado compartido.
En el próximo tema veremos reportes en consola: salida corta, detallada, trazas y tiempos de ejecución.