如何衡量覆盖率(在生产系统中)?

gue*_*tli 6 python code-coverage performance-testing

我想测量在生产系统中执行的 Python 代码的覆盖率。

我想回答这个问题:

哪些行经常执行(热点),哪些行从不使用(死代码)?

当然,这不能减慢我的生产站点的速度。

不是在谈论测量测试的覆盖率。

Ron*_*ers 8

我假设您不是在谈论另一个答案所指的测试套件代码覆盖率。这确实是 CI 的工作。

如果您想知道在您的生产系统中哪些代码路径经常被访问,那么您将不得不进行一些检测/分析。这将有成本。您不能免费添加测量值。你可以很便宜地完成它,通常你只会运行很短的时间,足够长的时间直到你拥有你的数据。

Python 有cProfile来做完整的分析,测量每个函数的调用计数等。这将为您提供最准确的数据,但可能会对性能产生相对较高的影响。

或者,您可以进行统计分析,这基本上意味着您可以在计时器上对堆栈进行采样,而不是对所有内容进行检测。即使采样率很高,这也可以便宜得多!缺点当然是精度损失。

尽管在 Python 中做起来非常容易,但这里的答案仍然有点多。不过,Nylas 团队一篇关于这个确切主题的优秀博客文章

下面的采样器是从 Nylas 博客中提取的,并进行了一些调整。启动后,它每毫秒触发一次中断并记录当前调用堆栈:

import collections
import signal

class Sampler(object):
    def __init__(self, interval=0.001):
        self.stack_counts = collections.defaultdict(int)
        self.interval = interval

    def start(self): 
        signal.signal(signal.VTALRM, self._sample)
        signal.setitimer(signal.ITIMER_VIRTUAL, self.interval, 0)

    def _sample(self, signum, frame):
        stack = []
        while frame is not None:
            formatted_frame = '{}({})'.format(
                frame.f_code.co_name,
                frame.f_globals.get('__name__'))
            stack.append(formatted_frame)
            frame = frame.f_back
        formatted_stack = ';'.join(reversed(stack))
        self.stack_counts[formatted_stack] += 1
        signal.setitimer(signal.ITIMER_VIRTUAL, self.interval, 0)

Run Code Online (Sandbox Code Playgroud)

你检查stack_counts一下你的程序做了什么。这些数据可以绘制在火焰图中,这使得非常明显地看到您的程序在哪些代码路径中花费的时间最多。


小智 -2

也许创建一个文本文件,并通过您的每个程序方法只需附加一些引用它的文本,例如“执行的方法一”。像查看器一样彻底运行 Web 应用程序 10 次,然后创建一个 Python 程序,读取文件并计算文件的特定部分,甚至计算模式,并将其添加到变量并输出变量。