摘要:由于构造函数不支持参数,必须使用配置文件。使用文件作为的配置文件一般的项目都是多进程,这需要分析子进程的覆盖率,需要用到配置文件。这里文档说在构造函数里使用参数可以限制,实测,没有用会删除文件,保证不会影响下次统计的结果。
关于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项目,需要修改创建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
摘要:简介是一种用于统计代码覆盖率的工具,通过它我们可以检测测试代码的有效性,即测试对被测代码的覆盖率如何。支持分支覆盖率统计,可以生成报告。 Coverage简介 Coverage是一种用于统计Python代码覆盖率的工具,通过它我们可以检测测试代码的有效性,即测试case对被测代码的覆盖率如何。Coverage支持分支覆盖率统计,可以生成HTML/XML报告。XML报告可以集成入Jenk...
摘要:被测脚本只有正常退出或者以信号退出才能出发,才能得到覆盖率结果。如果直接或者用其他信号终止进程,覆盖率结果将会丢失参考文章脚本覆盖率分析方法介绍。 关于Coverage Coverage是Python代码覆盖率分析工具,有关它的介绍和安装方法请见:Python代码覆盖率分析工具Coverage 用Python启动的web服务可以方便地使用Coverage分析其覆盖率,假设一个web服务...
摘要:本文会介绍新增的代码覆盖率功能如何收集数据如何基于它收集的数据来改进应用的性能。动态分析是指在应用运行状态下收集代码执行数据的过程,换句话说,覆盖率数据就是在代码执行过程中通过标记收集到的。 showImg(https://segmentfault.com/img/remote/1460000009013741); 共 1812 字,读完需 3 分钟。工欲善其事必先利其器,前端周刊本周...
摘要:最近团队在不断完善项目中的单元测试用例,会用到代码覆盖率分析,本来以为应该默认安装了,所以使用来生成报告,但是执行后提示如下错误这是因为没有安装或启用导致。 最近团队在不断完善项目中的单元测试用例,会用到代码覆盖率分析,本来以为 homestead 应该默认安装了 xdebug ,所以使用 phpunit --coverage-html ./tests/codeCoverage 来生成...
摘要:主要完成一下工作启动一个服务器,生成包含源代码和测试脚本的页面运行浏览器加载页面,并显示测试的结果如果开启检测,则当文件有修改时,执行继续执行以上过程。如果我们引入了一些其它的库,比如之类的,将源代码和库代码打包在一起后,覆盖率会更难看。。 前言 在前端开发中,测试常常是被忽略的一环。因此最近在研究前端自动化测试框架Karma,把个人的学习过程分享出来,希望对大家有帮助。 什么是Kar...
阅读 2308·2021-09-28 09:45
阅读 3597·2021-09-24 09:48
阅读 2258·2021-09-22 15:49
阅读 3094·2021-09-08 16:10
阅读 1589·2019-08-30 15:54
阅读 2320·2019-08-30 15:53
阅读 3016·2019-08-29 18:42
阅读 2865·2019-08-29 16:19