python pytest cprofile

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.



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:

  1. 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

  2. Para perfilar funciones específicas de py.test, 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 .