37

我已经确定了一些长期运行的 pytest 测试

py.test --durations=10

我现在想用 line_profiler 或 cprofile 之类的东西来检测其中一个测试。我真的很想从测试本身获取配置文件数据,因为 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代码,我做了两件事:

  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*()为了分析 py.test 特定的功能,例如line_profiler我将它们分成两部分以避免和之间的py.test混淆line_profiler

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

同样的方法适用于memory_profiler

于 2014-05-20T16:15:34.833 回答
10

您是否尝试过pytest-profiling插件?

于 2018-08-07T07:08:24.673 回答
1

我最近写了可能有用的 pytest-line-profiler 。它没有经过实战测试,所以请给我反馈(和帮助)。

于 2021-05-19T04:16:16.330 回答