如何在生产系统中测量覆盖率?

6
我希望测量在生产系统中执行的Python代码的覆盖率。 我想要得到这个问题的答案: 哪些代码行经常被执行(热点)和哪些代码行从未被使用(死代码)? 当然,这不能拖慢我的生产站点。 我并不是在谈论测试覆盖率。

你想要为哪种代码做这个?Django网络服务器还是其他的?另外,我希望你明白在生产环境中做这样的事情是不推荐的。 - Tarun Lalwani
我对“在生产系统中执行的代码”是什么意思也不太清楚 - 但您可以将该代码移动到私人存储库,并配置连续集成以获取覆盖范围。 - OverLordGoldDragon
3个回答

9
我假设您不是在谈论测试套件代码覆盖率,这是另一个答案所提到的。这确实是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)


你检查 stack_counts 以了解程序的运行情况。这些数据可以绘制成 火焰图,从而更容易地看出程序在哪些代码路径上花费了最多的时间。

因此,“生产系统”覆盖范围是指在生产中部署的代码覆盖率吗?例如,编译为可执行文件并查看用户使用时代码执行的频率--那么,我的答案确实是不相关的。 - OverLordGoldDragon
我们只能从问题中猜测,所以谁知道呢。我想这就是他的意思,是吧 :-) - Ronald
+1 for "This will have a cost. You cannot add measurements for free." 任何形式的测量都会引入一些开销。 - Terseus

0

如果我理解正确,您想了解用户最常使用应用程序的哪些部分。


TL;DR;

如果您不想手动完成,可以使用Python的度量框架之一。以下是其中一些:


通常情况下,这是通过函数级别完成的,实际上取决于应用程序;

  • 如果是具有互联网访问权限的桌面应用程序:

    您可以创建一个简单的数据库并收集调用您的函数的次数。为此,您可以编写一个简单的函数,并在要跟踪的每个函数内部调用它。之后,您可以定义一个异步任务将数据上传到互联网。

  • 如果是Web应用程序:

    您可以跟踪从js(大多数情况下首选用户行为跟踪)或Web API调用的函数。从外部开始向内部前进是一个好习惯。首先检测哪些端点经常被调用(如果您使用像nginx这样的代理,可以分析服务器日志以收集信息。这是最简单和最清洁的方法)。之后,在您想要跟踪的每个其他函数中插入记录器,然后每周或每月分析您的日志即可。

但是,如果您想逐行分析生产代码(这是一个非常糟糕的想法),您可以使用Python分析器启动应用程序。Python已经有一个:cProfile


-2
也许可以创建一个文本文件,在每个程序方法中引用一些文本,如“执行方法一”。像观察者一样彻底运行Web应用程序10次后,编写一个Python程序读取文件并计算其中特定部分或甚至模式,并将其添加到变量中并输出变量。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接