Can I run line_profiler over a pytest test?
Run pytest like this:
python3 -m cProfile -o profile -m pytest
You can even pass in optional arguments:
python3 -m cProfile -o profile -m pytest tests/worker/test_tasks.py -s campaigns
This will create a binary file called profile
in your current directory. This can be analyzed with pstats:
import pstatsp = pstats.Stats('profile')p.strip_dirs()p.sort_stats('cumtime')p.print_stats(50)
This will print the 50 lines with the longest cumulative duration.
To get cProfile
and line_profiler
to work with py.test
code, I did two things:
Extended the py.test test code with a call to pytest.main(), which made it executable with the python interpreter as the main driver:
# pytest_test.py:@profile # for line_profiler onlydef test_example(): x = 3**32 assert x == 1853020188851841# for profiling with cProfile and line_profilerimport pytestpytest.main(__file__)
Now you can run this test without
py.test
as the main driver using other tools:$ kernprof.py -l pytest_test.py$ python -m line_profiler pytest_test.py.lprof
or
$ python -m cProfile pytest_test.py
To profile py.test-specific functions such as
pytest_funcarg*()
withline_profiler
I split them in two to avoid confusion betweenpy.test
andline_profiler
:def pytest_funcarg__foo(request): return foo(request)@profiledef foo(request):...
The same method works for memory_profiler.