¿Puedo ejecutar line_profiler sobre una prueba pytest?

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 propia prueba, ya que la configuración o el desassembly 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.

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 que cProfile y line_profiler funcionen con el código py.test , hice dos cosas:

  1. Extendió el código de prueba py.test con una llamada a pytest.main (), que lo hizo ejecutable con el intérprete de python como el 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 
  2. Para perfilar funciones específicas de pytest_funcarg*() como pytest_funcarg*() con line_profiler , las line_profiler en dos para evitar confusiones entre py.test y line_profiler :

     def pytest_funcarg__foo(request): return foo(request) @profile def foo(request): ... 

El mismo método funciona para memory_profiler .

¿Has probado el plugin pytest-profiling ?