coverage.py的覆盖率统计原理

转载 2015年07月08日 10:18:23

原文出处:http://blog.theerrorlog.com/how-coverage-py-produce-coverage-statistics.html


在Erlang下,用rebar可以在运行单元测试的同时调用cover模块,从而得 到单元测试的覆盖率,这是很方便的一个功能。最近发现Python下的nose也可 以通过--with-coverage选项达到类似的效果,而这个选项实际上是调用了 coverage.py. 出于好奇,我研究了一下coverage.py的工作原理。

coverage.py的使用方法

抄一下coverage.py主页的例子:

  1. coverage命令运行你的程序

    $ coverage run my_program.py arg1 arg2 
    blah blah ..your program's output.. blah blah
    
  2. 生成报告

    1
    2
    3
    4
    5
    6
    7
    $ coverage report -m
    Name                      Stmts   Miss  Cover   Missing
    -------------------------------------------------------
    my_program                   20      4    80%   33-35, 39
    my_other_module              56      6    89%   17-23
    -------------------------------------------------------
    TOTAL                        76     10    87%
    
  3. 或者,生成更漂亮的HTML报告

    $ coverage html
    

好吧对于一个开发工具来说,coverage算是挺成功的,因为够傻瓜。和 nosetests搭配使用的时候甚至更简单,加一个参数就可以了,“猴子都能学 会”……

既然这里有个脚本入口coverage,我们就从这里开始吧~

工作原理

首先从源码库把代码clone下来,观察一下setup.py

1
2
3
4
5
scripts = [                                                                      
    'coverage = coverage:main',                                                  
    'coverage%d = coverage:main' % sys.version_info[:1],                         
    'coverage-%d.%d = coverage:main' % sys.version_info[:2],                     
    ]

这里说明,coverage命令其实是调用了coverage模块下的main函数,根据这个 函数的内容——为了简洁起见这里省略掉一堆处理命令行参数的代码——我们可以跟踪到 coverage/control.py文件中的Coverage类。

这个类包含了所有从数据采集到生成报告的代码,我们只关心它如何采集到程序执行 数据就好了。而“采集数据”这个操作,通过这里的源码可以推断出,是由 coverage/collector.py中的Collector类和PyTracer类,又或者是CTracer 类合作完成的。

PyTracerCTracer其实在逻辑上是等价的,只不过一个是纯Python实现,而另 一个是C语言实现。为什么会这样呢?我们先继续看下去……

既然这两个类是一样的,我们还是来看稍微漂亮一点的Python版本吧。PyTracer 的start函数有句docstring说,这个函数是用来“Return a Python function suitable for use with sys.settrace()”的。

好吧,真相大白了,coverage.py利用了Python虚拟机的trace机制。我怎么就没想 到呢?

sys.settrace(...)

这个函数的文档在这里,所以参数和用法说明什么的我就省略了。实际上 这是Python程序调试机制的核心——几乎每种虚拟机或者操作系统,都有类似的 机制,用于干预其上执行的程序,可以认为这是给对应的调试器开的“后门”。 例如Erlang下有erlang:trace(...),POSIX系统下也有ptrace; Erlang的dbg模块正是基于erlang:trace(...)的,而gdb也是在ptrace基 础上工作的。

大家都知道调试器都是牛逼到可以把运行中的程序拆开再装回去的,它们依赖 的trace机制自然也是大杀器。但是这货通常要启动各种钩子(Hook),会严 重拖慢被trace的程序的运行速度,所以一般不会用在生产环境中。

这也就解释了为什么coverage.py里会有两个tracer:tracer代码基本上在 Python虚拟机的每步执行中都要被调用一遍,所以有一个C语言实现是能有效 提高效率的。那为什么还需要Python实现?这是为了支持CPython以外的虚拟 机,像PyPy、Jython之类。

其他利用trace机制的有趣玩意

pycallgraph能生成Python程序中的函数调用关系图(Call Graph)。

另外我在很~久之前用ptrace做了一个更改cd命令行为的小玩具 :)(转载注:作者写的)


Python代码覆盖工具coverage.py介绍

coverage.py,这个工具比较简单,我用easy_install安装的($ easy_install coverage),非常顺利。由于python不需要编译链接,所以这个工具使用非常简单。 ...
  • windone0109
  • windone0109
  • 2013年11月13日 14:44
  • 3646

Flask Web 开发 测试

国庆节沦陷在RESTFUL API这个章节里了。。。横竖没看懂 后来请教了其他筒子关于REST API的概念,少许有些理解,就是主要集中在资源的获取上,同样的资源格式,比如JSON,可以提供给不同的终...
  • bestallen
  • bestallen
  • 2016年10月09日 10:58
  • 1464

使用nose进行python自动化测试

一、为什么使用nose? 编写测试更容易。 nose可以自动识别继承于unittest.TestCase的测试单元,并执行测试,而且,nose也可以测试非继承于unittest.TestCase...
  • zcabcd123
  • zcabcd123
  • 2017年02月07日 16:19
  • 1480

python coverage代码覆盖率工具

python coverage代码覆盖率工具   打命令coverage加测试文件,就可以得到覆盖率,可以生成html格式的报告,每次运行一个文件都会生成一个.coverage文件,需要将co...
  • chenglinhust
  • chenglinhust
  • 2016年02月29日 00:28
  • 1265

python测试框架nose研究

最近在使用openstack自动化测试工具tempest,tempest中用到了nose,这里先了解一下nose的用法吧。 关于nose的安装什么的就不介绍了,这个可以在网上搜一搜。 这里主要介绍no...
  • chenchiheng
  • chenchiheng
  • 2015年07月20日 22:50
  • 4114

Python 代码覆盖率统计工具 coverage.py

Python 代码覆盖率统计工具 coverage.py coverage.py是一个用来统计python程序代码覆盖率的工具。它使用起来非常简单,并且支持最终生成界面友好的html...
  • luoye7422
  • luoye7422
  • 2014年12月23日 22:16
  • 444

python代码覆盖率工具——coverage

今天发现了一个好用的python代码覆盖率检查工具:coverage, 可以高亮显示代码中哪些语句未被执行,哪些执行了,方便单测。 环境: Linux x86_64 (不能连外网) 下载: ...
  • abcjennifer
  • abcjennifer
  • 2015年09月20日 17:22
  • 10586

使用coverage工具统计python单元测试覆盖率

原文:http://www.cnblogs.com/zoro-robin/p/5612472.html Coverage简介 Coverage是一种用于统计Python代码覆盖率的工具,通过它可以...
  • xiaoxinyu316
  • xiaoxinyu316
  • 2016年12月16日 17:08
  • 1103

python代码覆盖率

python代码覆盖率,使用的coverage包,生成代码覆盖率报告。 1 安装coverage: $ pip install coverage2 python代码覆盖率生成:   执行代码覆盖率...
  • qq_37023538
  • qq_37023538
  • 2016年12月28日 19:29
  • 1267

使用coverage统计python web项目的代码覆盖率

在使用python+selenium过程中,有时候考虑代码覆盖率,所以专门查了一下python的coverage,所以特此记录 1.安装coverage 自己电脑安装了pip的   直接: pip...
  • a136332462
  • a136332462
  • 2017年01月04日 16:56
  • 408
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:coverage.py的覆盖率统计原理
举报原因:
原因补充:

(最多只允许输入30个字)