博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
使用Coverage分析WSGI项目的代码覆盖率
阅读量:6827 次
发布时间:2019-06-26

本文共 4150 字,大约阅读时间需要 13 分钟。

关于Coverage

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

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

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

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

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

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

所以,你是没有办法像一样用Coverage命令行coverage run的形式启动它的。必须使用Coverage api。

关于Coverage api,参见文档:

还需要用到一点.coveragerc配置,参见文档:

修改wsgi.py文件

对于WSGI项目,需要修改创建WSGI application的文件,加入coverage api代码。

本来它的代码是这样的:

import osos.environ.setdefault("DJANGO_SETTINGS_MODULE", "xxx.settings")from django.core.wsgi import get_wsgi_applicationapplication = get_wsgi_application()

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

###########import coverage, atexitcov = coverage.Coverage(branch=True, concurrency="gevent", config_file=".coveragerc")cov.start()###########import osos.environ.setdefault("DJANGO_SETTINGS_MODULE", "xxx.settings")from django.core.wsgi import get_wsgi_applicationapplication = 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是指要统计分支代码覆盖率,加上这个参数可使统计更精确,具体区别参见文档:

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

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

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

一般的Web项目都是多进程,这需要Coverage分析子进程的覆盖率,需要用到Coverage配置文件。

官方文档参见:

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

[run]branch = Trueparallel = True

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

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

coverage run --parallel-mode xxx.py

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

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

atexit.register方法

关于wsgi项目的覆盖率统计,最初我看到的资料(也是唯一的)是:

\\

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

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$ lltotal 2708drwxr-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 combinecoverage 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_jenkins

  • XML(集成到Sonar):

    xml_sonar

  • HTML:

    html_report

转载地址:http://roykl.baihongyu.com/

你可能感兴趣的文章
this的使用方法
查看>>
面向对象的开山鼻祖——“Jolt大奖精选丛书”有奖征文
查看>>
C语言例题系列------第十一天
查看>>
卖了,珠海
查看>>
对抗海量表格数据,【华为2012实验室】没有选择复仇者联盟
查看>>
Centos安装VMware
查看>>
arp欺骗
查看>>
不可不知 DDoS的***原理与防御方法
查看>>
SVN基于MySQL认证
查看>>
redhat5下安装MySQL-5.6,默认密码无法进入的解决办法
查看>>
七、Asp.Net MVC4.0开发CMS系统案例之用户群组模块
查看>>
为什么一般的性能测试要在局域进行?
查看>>
CCNP学习之路之单臂路由router-on-a-stick
查看>>
Linux ---算术运算
查看>>
2017年9月
查看>>
show processlist 其中status详解(适用于所有概况)
查看>>
将Centos的yum源更换为阿里云源
查看>>
利用Fiddler或Charles进行mock数据
查看>>
探寻TP-Link路由器的登录验证
查看>>
CS Website
查看>>