37

私はいくつかの長時間実行されている pytest テストを特定しました

py.test --durations=10

line_profiler や cprofile などを使用して、これらのテストの 1 つを計測したいと考えています。pytestのセットアップまたは破棄が遅いものの一部である可能性があるため、テスト自体からプロファイルデータを取得したいと本当に思っています。

ただし、通常、line_profiler または cprofile がどのように関与しているかを考えると、それらを pytest で動作させる方法は明確ではありません。

4

4 に答える 4

41

次のように pytest を実行します。

python3 -m cProfile -o profile -m pytest

オプションの引数を渡すこともできます。

python3 -m cProfile -o profile -m pytest tests/worker/test_tasks.py -s campaigns

profileこれにより、現在のディレクトリに呼び出されるバイナリ ファイルが作成されます。これは pstats で分析できます。

import pstats
p = pstats.Stats('profile')
p.strip_dirs()
p.sort_stats('cumtime')
p.print_stats(50)

これにより、累積期間が最も長い 50 行が出力されます。

于 2014-06-24T16:39:40.437 に答える
18

コードを取得cProfileline_profilerて操作するためにpy.test、次の 2 つのことを行いました。

  1. pytest.main() の呼び出しで py.test テスト コードを拡張しました。これにより、メイン ドライバーとして Python インタープリターで実行可能になりました。

    # 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__)
    

    py.testこれで、他のツールを使用してメイン ドライバーなしでこのテストを実行できます。

    $ kernprof.py -l pytest_test.py
    $ python -m line_profiler pytest_test.py.lprof
    

    また

    $ python -m cProfile pytest_test.py
    
  2. pytest_funcarg*()withなどの py.test 固有の関数をプロファイリングするには、 とline_profilerの混乱を避けるために 2 つに分割します。py.testline_profiler

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

同じ方法がmemory_profilerにも機能します。

于 2014-05-20T16:15:34.833 に答える