资讯专栏INFORMATION COLUMN

使用Coverage分析WSGI项目的代码覆盖率

YFan / 1903人阅读

摘要:由于构造函数不支持参数,必须使用配置文件。使用文件作为的配置文件一般的项目都是多进程,这需要分析子进程的覆盖率,需要用到配置文件。这里文档说在构造函数里使用参数可以限制,实测,没有用会删除文件,保证不会影响下次统计的结果。

关于Coverage

Coverage是Python代码覆盖率分析工具,有关它的介绍和安装方法请见:
Python代码覆盖率分析工具Coverage

用Python启动的web服务可以方便地使用Coverage分析其覆盖率,具体请见:
使用Coverage分析Python web项目的代码覆盖率

下面来说说WSGI项目的分析,这方面的资料较少,需要一定摸索。

使用Coverage分析WSGI项目的代码覆盖率

一个uWSGI + Django的项目,它的启停命令如下:

sudo uwsgi --ini /xxx/uwsgi.cfg
sudo pkill -9 -f /xxx/uwsgi.cfg

所以,你是没有办法像使用Coverage分析Python web项目的代码覆盖率一样用Coverage命令行coverage run的形式启动它的。必须使用Coverage api。

关于Coverage api,参见文档:
http://coverage.readthedocs.org/en/latest/api_coverage.html

还需要用到一点.coveragerc配置,参见文档:
http://coverage.readthedocs.org/en/latest/config.html

修改wsgi.py文件

对于WSGI项目,需要修改创建WSGI application的文件,加入coverage api代码。
本来它的代码是这样的:

import os

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xxx.settings")

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()

需要在其前后加入coverage控制,以下代码须安装Coverage 4.0

###########
import coverage, atexit
cov = coverage.Coverage(branch=True, concurrency="gevent", config_file=".coveragerc")
cov.start()
###########
import os

os.environ.setdefault("DJANGO_SETTINGS_MODULE", "xxx.settings")

from django.core.wsgi import get_wsgi_application
application = get_wsgi_application()
###########
def save_coverage():
    cov.stop()
    cov.save()
atexit.register(save_coverage)
###########

解释一下这一句:

cov = coverage.Coverage(branch=True, concurrency="gevent", config_file=".coveragerc")

branch是指要统计分支代码覆盖率,加上这个参数可使统计更精确,具体区别参见文档:http://coverage.readthedocs.org/en/latest/branch.html

concurrency指被测代码使用的concurrency library,选项有greenlet, eventlet, gevent, thread(默认)。本项目使用了gevent,这里设置成gevent。

config_file指Coverage的配置文件,这个配置文件主要用于指定parallel这个参数。由于Coverage构造函数不支持parallel参数,必须使用配置文件。

使用.coveragerc文件作为Coverage的配置文件

一般的Web项目都是多进程,这需要Coverage分析子进程的覆盖率,需要用到Coverage配置文件。
官方文档参见:http://coverage.readthedocs.org/en/latest/config.html

在这个项目中,.coveragerc内容如下,它需要与coverage api所在路径一致,即与wsgi.py同目录:

[run]
branch = True
parallel = True

这个配置使Coverage监测被测代码子进程的覆盖率,如果被测代码是多进程的,必须使用此参数。

在Coverage命令行启动中,可以这样指定:

coverage run --parallel-mode xxx.py

但在api方式中,只能使用config_file设置。

关于Coverage构造函数config_file参数,文档说不设置默认不使用配置文件,实际不是,只要有.coveragerc文件,就会使用其中的配置。

atexit.register方法

关于wsgi项目的覆盖率统计,最初我看到的资料(也是唯一的)是:
http://stackoverflow.com/questions/19025336/how-to-get-coverage-data-from-a-django-app-when-running-in-gunicorn

里面提到需要这样保存覆盖率结果:

def save_coverage():
    cov.stop()
    cov.save()
atexit.register(save_coverage)

意思是使用atexit.register注册回调函数,以在程序退出时保存结果。但为了触发atexit.register,需要对被测进程执行kill -HUP。

经过实测,有的项目是不需要执行kill -HUP的。子进程在收到请求时会自动退出,保存覆盖率结果,同时主进程会重启一个子进程。

这就意味着加入Coverage api以后,服务收到的每个请求都会重启一个子进程!这会严重影响性能。所以这种覆盖率统计只能在线下做。

Coverage结果收集

经过如上修改后,正常用uWSGI启动服务:

sudo uwsgi --ini /xxx/uwsgi.cfg

启动后,执行测试case,可以见到wsgi.py所在目录下出现多个.coverage开头的文件,文件名格式为.coverage.<机器名>.<进程号>.<随机数>。

xxx@xxx:/xxx$ ll
total 2708
drwxr-xr-x 11 root root   4096 Sep 25 11:46 ./
drwxr-xr-x  6 root root   4096 Sep 25 08:30 ../
-rw-rw-rw-  1 root root 284691 Sep 25 11:46 .coverage.xxx.15845.747211
-rw-rw-rw-  1 root root 284917 Sep 25 11:45 .coverage.xxx.15846.592706
-rw-rw-rw-  1 root root 284274 Sep 25 11:45 .coverage.xxx.15847.688607
-rw-rw-rw-  1 root root 284583 Sep 25 11:45 .coverage.xxx.15858.136003
-rw-rw-rw-  1 root root 284274 Sep 25 11:46 .coverage.xxx.15867.746159
-rw-rw-rw-  1 root root 284691 Sep 25 11:46 .coverage.xxx.15876.004083
-rw-rw-rw-  1 root root 283820 Sep 25 11:46 .coverage.xxx.15886.921243

有7个文件,意味着发送了7个请求。

测试结束后,需要合并测试结果,生成报告:

coverage combine
coverage report -m yyy/*
coverage html yyy/*
coverage xml yyy/*
coverage erase

combine会合并7个文件成1个.coverage,因为最后Coverage统计的是.coverage的结果。

report/html/xml:直接在终端显示报告/生成html报告/生成xml报告,后面加路径可以限制显示哪些代码的覆盖率。(这里文档说在Coverage构造函数里使用include参数可以限制,实测,没有用…)

erase会删除.coverage文件,保证不会影响下次统计的结果。

生成的报告非常清晰,html和xml可以直接点击进入代码文件查看。

coverage report结果:

  Name                         Stmts   Miss Branch BrPart  Cover   Missing
  ------------------------------------------------------------------------
  yyy/__init__.py           0      0      0      0   100%   
  yyy/111.py      89     12     16      3    86%   82, 89-91, 104, 108-110, 123, 127-129, 81->82, 103->104, 122->123
  yyy/222.py           60     44     14      0    22%   30-89, 97-103
  yyy/333.py        268     31     74     16    85%   48, 56-57, 70, 78-79, 92, 109, 117, 131, 154, 175, 195-206, 217, 235, 256, 277, 304, 327, 344, 366-367, 45->48, 67->70, 89->92, 106->109, 116->117, 128->131, 151->154, 172->175, 184->181, 214->217, 232->235, 253->256, 274->277, 301->304, 324->327, 341->344
  ……(略)
  ------------------------------------------------------------------------
  TOTAL                         7180   1872   1976    414    70%   

XML(集成到Jenkins):

XML(集成到Sonar):

HTML:

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/37616.html

相关文章

  • Python代码盖率分析工具Coverage

    摘要:简介是一种用于统计代码覆盖率的工具,通过它我们可以检测测试代码的有效性,即测试对被测代码的覆盖率如何。支持分支覆盖率统计,可以生成报告。 Coverage简介 Coverage是一种用于统计Python代码覆盖率的工具,通过它我们可以检测测试代码的有效性,即测试case对被测代码的覆盖率如何。Coverage支持分支覆盖率统计,可以生成HTML/XML报告。XML报告可以集成入Jenk...

    zombieda 评论0 收藏0
  • 使用Coverage分析Python web项目代码盖率

    摘要:被测脚本只有正常退出或者以信号退出才能出发,才能得到覆盖率结果。如果直接或者用其他信号终止进程,覆盖率结果将会丢失参考文章脚本覆盖率分析方法介绍。 关于Coverage Coverage是Python代码覆盖率分析工具,有关它的介绍和安装方法请见:Python代码覆盖率分析工具Coverage 用Python启动的web服务可以方便地使用Coverage分析其覆盖率,假设一个web服务...

    marser 评论0 收藏0
  • Chrome DevTools 代码盖率功能详解

    摘要:本文会介绍新增的代码覆盖率功能如何收集数据如何基于它收集的数据来改进应用的性能。动态分析是指在应用运行状态下收集代码执行数据的过程,换句话说,覆盖率数据就是在代码执行过程中通过标记收集到的。 showImg(https://segmentfault.com/img/remote/1460000009013741); 共 1812 字,读完需 3 分钟。工欲善其事必先利其器,前端周刊本周...

    robin 评论0 收藏0
  • phpunit 单元测试之代码盖率

    摘要:最近团队在不断完善项目中的单元测试用例,会用到代码覆盖率分析,本来以为应该默认安装了,所以使用来生成报告,但是执行后提示如下错误这是因为没有安装或启用导致。 最近团队在不断完善项目中的单元测试用例,会用到代码覆盖率分析,本来以为 homestead 应该默认安装了 xdebug ,所以使用 phpunit --coverage-html ./tests/codeCoverage 来生成...

    blankyao 评论0 收藏0
  • 前端单元测试之Karma环境搭建

    摘要:主要完成一下工作启动一个服务器,生成包含源代码和测试脚本的页面运行浏览器加载页面,并显示测试的结果如果开启检测,则当文件有修改时,执行继续执行以上过程。如果我们引入了一些其它的库,比如之类的,将源代码和库代码打包在一起后,覆盖率会更难看。。 前言 在前端开发中,测试常常是被忽略的一环。因此最近在研究前端自动化测试框架Karma,把个人的学习过程分享出来,希望对大家有帮助。 什么是Kar...

    mrli2016 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<