为啥coverage.py 不能正确测量Django 的runserver 命令?

Posted

技术标签:

【中文标题】为啥coverage.py 不能正确测量Django 的runserver 命令?【英文标题】:Why doesn't coverage.py properly measure Django's runserver command?为什么coverage.py 不能正确测量Django 的runserver 命令? 【发布时间】:2011-10-26 10:27:45 【问题描述】:

我应该知道这个问题的答案,但我不知道:如果您尝试像这样测量 Django 项目的覆盖率:

coverage run manage.py runserver 

您会得到遗漏所有实际代码的覆盖率测量。过程早期的某些事情正在停止测量,或者所有实际工作都发生在一个根本没有被测量的新环境中。

有人可以指出过程中测量失败的特定点,以便我可以尝试修复coverage.py,以便它可以按照人们期望的方式正确测量它吗?

【问题讨论】:

【参考方案1】:

如果你这样运行,你会遇到同样的问题吗?

coverage run manage.py runserver --noreload

没有--noreload,另一个进程在幕后启动。一个进程运行服务器,另一个进程查找代码更改并在进行更改时重新启动服务器。很有可能,您正在监视进程而不是服务进程上运行覆盖。

看看django/core/management/commands/runserver.pydjango/utils/autoreload.py

更新:我运行了覆盖命令,然后使用pslsof 查看发生了什么。这是我观察到的:

ps output:

UID        PID  PPID  C STIME TTY          TIME CMD

vinay    12081  2098  0 16:37 pts/0    00:00:00 /home/vinay/.virtualenvs/watfest/bin/python /home/vinay/.virtualenvs/watfest/bin/coverage run manage.py runserver
vinay    12082 12081  2 16:37 pts/0    00:00:01 /home/vinay/.virtualenvs/watfest/bin/python manage.py runserver

lsof output:

python    12082      vinay    5u     IPv4      48294      0t0        TCP localhost:8000 (LISTEN)

IOW,即使在任何重新加载之前,也有两个进程,并且侦听 TCP 端口的那个不是正在运行覆盖的那个。

这是我看到的--noreload

ps output:

UID        PID  PPID  C STIME TTY          TIME CMD

vinay    12140  2098  5 16:44 pts/0    00:00:00 /home/vinay/.virtualenvs/watfest/bin/python /home/vinay/.virtualenvs/watfest/bin/coverage run manage.py runserver --noreload

lsof output:

coverage  12140      vinay    4u     IPv4      51995      0t0        TCP localhost:8000 (LISTEN)

因此,在--noreload 案例中为什么覆盖不起作用并不明显。在我对--noreload 的非常简短的测试中,我得到了我的视图代码的覆盖范围,如以下摘录所示:

festival/__init__   8      7    13%
manage              9      4    56%
settings           33      1    97%

【讨论】:

是的,我忘了在问题中提到这一点:--noreload 不会改变问题。严格来说,自动重新加载在重新加载之前不会启动一个新进程:起初,它只是另一个监视文件更改的线程,如果它们发生了,就会产生另一个进程(我认为)。 感谢您提供的详细信息,自动重载在我的脑海中一直很模糊,您已经展示了它是如何工作的。出于某种原因,我之前的测试表明 --noreload 没有帮助,但现在我再次尝试,它起作用了! 非常好!非常适合在外部集成测试中运行。 我在使用 Flask 时遇到了同样的问题,这个答案为我指明了正确的方向。像这样运行 Flask:coverage run manage.py runserver -r

以上是关于为啥coverage.py 不能正确测量Django 的runserver 命令?的主要内容,如果未能解决你的问题,请参考以下文章

coverage.py:排除文件

如果 py.test 从另一个目录执行它,coverage.py 不会覆盖脚本

为啥通过 AJAX 无限滚动加载的内容的高度在加载后没有正确测量?

从 coverage.py 运行测试与从测试运行器运行覆盖

Coverage.py 警告:未收集数据。 (未收集数据)

通过 pytest 使用多进程处理时如何测量覆盖率?