python - ¿Puedo ejecutar line_profiler sobre una prueba pytest?
cprofile (3)
He identificado algunas pruebas pytest de larga duración con
py.test --durations=10
Me gustaría instrumentar una de esas pruebas ahora con algo como line_profiler o cprofile. Realmente quiero obtener los datos del perfil de la prueba en sí mismo, ya que la configuración o el desmontaje de pytest podrían ser parte de lo que es lento.
Sin embargo, dado que line_profiler o cprofile normalmente está involucrado, no me queda claro cómo hacer que funcionen con pytest.
¿Has probado el plugin pytest-profiling ?
Ejecutar pytest de esta manera:
python -m cProfile -o profile $(which py.test)
Incluso puedes pasar argumentos opcionales:
python -m cProfile -o profile $(which py.test) /
tests/worker/test_tasks.py -s campaigns
Esto creará un archivo binario llamado profile
en su directorio actual. Esto se puede analizar con pstats:
import pstats
p = pstats.Stats(''profile'')
p.strip_dirs()
p.sort_stats(''cumtime'')
p.print_stats(50)
Esto imprimirá las 50 líneas con la duración acumulada más larga.
Para hacer que cProfile
y line_profiler
funcionen con el código py.test
, hice dos cosas:
Extendió el código de prueba py.test con una llamada a pytest.main (), lo que lo hizo ejecutable con el intérprete de python como controlador principal:
# pytest_test.py: @profile # for line_profiler only def test_example(): x = 3**32 assert x == 1853020188851841 # for profiling with cProfile and line_profiler import pytest pytest.main(__file__)
Ahora puede ejecutar esta prueba sin
py.test
como el controlador principal utilizando otras herramientas:$ kernprof.py -l pytest_test.py $ python -m line_profiler pytest_test.py.lprof
o
$ python -m cProfile pytest_test.py
Para perfilar funciones específicas de py.test, como
pytest_funcarg*()
conline_profiler
, lasline_profiler
en dos para evitar confusiones entrepy.test
yline_profiler
:def pytest_funcarg__foo(request): return foo(request) @profile def foo(request): ...
El mismo método funciona para memory_profiler .