Can I run line_profiler over a pytest test?

江枫思渺然 提交于 2019-12-03 04:33:53

Run pytest like this:

python -m cProfile -o profile $(which py.test)

You can even pass in optional arguments:

python -m cProfile -o profile $(which py.test) \
    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 pstats
p = 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:

  1. 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 only
    def test_example():
        x = 3**32
        assert x == 1853020188851841
    
    # for profiling with cProfile and line_profiler
    import pytest
    pytest.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
    
  2. To profile py.test-specific functions such as pytest_funcarg*() with line_profiler I split them in two to avoid confusion between py.test and line_profiler:

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

The same method works for memory_profiler.

Have you tried the pytest-profiling plugin?

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!